Karunaratne held one end for a long period to score 126 before a dogged unbeaten inning of Dilruwan Perera helped Sri Lanka reach 268-7 at stumps on the fourth day to stretch their lead over the visitors to 139 runs.
This much lead looked a distant possibility once Mustafizur and Shakib triggered a collapse in Sri Lankan innings in the post lunch session but Karunaratne hang on to score 126 before Perera hit an 26 off 126 balls.
Perera received support from tail-enders Rangana Herath (9 off 32 balls) and Suranga Lakmal, 14 not out as the hosts were hoping to expand their lead to give their bowlers something to fight with.
Bangladesh struck in the day's second over through off-spinner Mehedi Hasan, who spun one sharply to bowl out opener Upul Tharanga for 26 after Sri Lanka resumed on 54-0.
But Karunaratne and Kusal Mendis shared 86-run for the second wicket to help the hosts wipe out their first innings deficit and put Sri Lanka in good stead to set up decent target for Bangladesh.
"I think the wicket is really good. We lost a few wickets and after that we could not capitalise," said Karunaratne.
"Three of our main batsmen got out in one phase. At the end of the day we have stay positive. We just wanted to play our normal game," he said.
"If we can get 200-plus, it's a good score. We are happy if they can bat till we get 200 or more."
Mustafizur helped Bangladesh bounce back in the contest with quick strikes in his second spell as Mendis edged an angular ball outside the off-stump to wicketkeeper Mushfiqur Rahim for 36.
Five overs later it was the turn of first-innings centurion Dinesh Chandimal, who played a loose drive to be caught behind for five.
Asela Gunaratne was adjudged leg-before for seven off Shakib without offering any shot before Mustafizur struck again to hand Dhananjaya de Silva a duck.
Niroshan Dickwella survived a close call for lbw but could not make use of it giving Mushfiqur his fourth catch down the leg off Shakib to depart for five.
An edge off Mustafizur flew to third man boundary to earn Karunaratne his fifth Test century but he fell in the final session edging Shakib to Soumya Sarkar at slip.
Perera batted with grit but should have been dismissed for four had umpires Aleem Dar not made an error of judgment with Bangladesh already completing their quota of reviews.
Taijul Islam removed Herath, who was equally stubborn but Bangladesh were yet to find an answer for Perera's ultra-defensive batting, much-needed effort for Sri Lanka though.
Mustafizur claimed 3-52 for Bangladesh while Shakib finished the day with 3-61.