Starting the day at 209 for 2, Karunartane completed his sixth Test hundred and was unbeaten on 136 off 288 balls with 16 boundaries to his credit. He has now remained undefeated for six hours.
Skipper Mathews was batting on 28 with the duo putting up 61 runs for the unbroken fifth wicket stand after the hosts were 241 for 4 at one stage.
Sri Lanka still trail by 137 runs and have six wickets in hand to avoid an innings defeat.
At the start, Karunaratne added 40 runs with nightwatchman Malinda Pushpakumara (16) for the third wicket.
The two continued stonewalling the Indian attack, but a few runs were added too. India struggled to make things happen as they failed to latch on to any half-chances offered by the nightwatchman.
The big moment of the session came in the 66th over when KL Rahul dropped Karunaratne (then on 95) at short leg off Ravindra Jadeja (1-113).
The opener didn’t offer any more chances thereafter reaching three-figure mark in 224 balls.
India were then given a lucky break as Pushpakumara played a horrific reverse sweep off Ashwin (1/106) in the 73rd over and was bowled, gifting his wicket after doing all the hard work.
It became a double blow as Jadeja then had Dinesh Chandimal (2) caught at slip in the next over, with Ajinkya Rahane holding a sharp catch diving to his right.
The visitors took the second new ball as soon as it became available, but Karunaratne and Mathews played watchful cricket given the vitality of this passage of play.
India did bring on its pacers, Mohammed Shami (0-27) and Umesh Yadav (1-39), for short spells with the new ball but they were unable to provide any breakthroughs.
Sri Lanka crossed the 300-mark in the 90th over, with Karunaratne and Mathews bringing up their 50-partnership off 71 balls. (PTI)