Two wickets in two balls by left-arm spinner Rangana Herath in the last half hour of play on the third day tilted the balance of the second Test towards Sri Lanka on Monday.
By stumps Bangladesh, who trailed Sri Lanka by 106 after the first innings, were 158 for four wickets - an overall lead of 52.
Mominul Haque scored an attractive half-century in the first innings and was unbeaten on 36 second time around with Mushfiqur Rahim on seven.
Both batsmen would have been out before the close had the Sri Lankan fielders been sharper.
Mominul was put down at mid-on by Nuwan Kulasekara when he was on 30 and Angelo Mathews missed Mushfiqur at slip also off Herath, who ended the day with figures of three for 45.
Mohammad Ashraful became Herath's first victim when he was bowled for four by a quicker delivery in the second over after tea when his off stump was sent tumbling.
A stand of 47 followed between Jahurul Islam and Mominul that carried Bangladesh to 143-2 before Herath struck twice in his 19th over.
He changed the complexion of the game by having Jahurul stumped by Dinesh Chandimal for 48 when the batsman lost his patience and charged up the wicket.
On the next ball, Mahmudullah was beaten up by a tossed up delivery from Herath and had his off stump knocked out.
Mushfiqur survived the hat-trick ball and was lucky to be there at the close.
Openers Tamim Iqbal and Jahurul provided a strong start to help Bangladesh reach 93 for one at tea.
On a surface which had flattened out at the R Premadasa Stadium, Tamim and Jahurul batted confidently.
Tamim, who missed the first Test through injury, was the aggressor in the partnership reaching his fifty off 67 balls with the help of one six and four fours.
He was dropped on 12 when Suranga Lakmal failed to hold a knee-high return catch.
A bowling change by Sri Lanka captain Angelo Mathews brought about the dismissal of Tamim, who tried to cut a ball from Shaminda Eranga but only succeeded in chopping it onto his stumps to depart for 59.
Earlier, Sri Lanka resumed on 294 for six and a lot depended on how long Kumar Sangakkara could bat on to give the hosts a healthy first innings lead.
Starting the day on 127, Sangakkara added only 12 runs to his overnight score when he went for a drive off Abul Hasan and, after a long delay, the third umpire ruled him out caught behind by Mushfiqur.
Sangakkara scored 139 off 289 balls and hit 11 fours in what was his third century in this series.
Sohag Gazi bowled Herath for three and dismissed Kulasekara for 22 when the batsman gave Mushfiqur his fifth catch of the innings as the spinner finished with figures of three for 111.
Mahmudullah then removed Shaminda Eranga (15) as Sri Lanka were all out for 346 in their first innings.
Bangladesh first innings 240
Sri Lanka first innings (294-6 overnight)
D. Karunaratne c Mushfiqur b Abul 17
T. Dilshan Mushfiqur b Robiul 0
K. Sangakkara c Mushfiqur b Abul 139
L. Thirimanne c Mushfiqur b Robiul 0
A. Mathews c Mahmudullah b Gazi 16
D. Chandimal b Rubel 102
K. Vithanage c Mominul b Rubel 12
N. Kulasekara c Mushfiqur b Gazi 22
R. Herath b Gazi 3
S. Eranga c Ashraful b Mahmudullah 15
S. Lakmal not out 0
Extras (b-2, lb-2, nb-10, w-6) 20
Total (all out; 111.3 overs) 346
Fall of wickets: 1-7, 2-39, 3-43, 4-69, 5-264, 6-280, 7-316, 8-323, 9-346.
Bowling: Robiul Islam 15-1-52-2 (nb-7), Sohag Gazi 39-4-111-3, Abul Hasan 23-4-80-2 (w-1), Rubel Hossain 17-5-45-2 (nb-3, w-1), Mahmudullah 11.3-1-37-1, Mominul Haque 2-0-6-0, Mohammad Ashraful 2-0-9-0, Nasir Hossain 2-0-2-0.
Bangladesh second innings
Tamim Iqbal b Eranga 59
Jahrul Islam st Chandimal b Herath 48
Mohammad Ashraful b Herath 4
Mominul Haque not out 36
Mahmudullah b Herath 0
Mushfiq ur Rahim not out 7
Extras: (lb-3, nb-1) 4
Total: (four wickets, 69 overs) 158
Fall of wickets: 1-91, 2-96, 3-143, 4-143
Bowling: Kulasekara 7-0-21-0, Lakmal 8-1-24-0, Herath 23-7-45-3, Dilshan 19-3-40-0, Eranga 9-3-17-1 (nb1), Mathews 3-2-8-0.
Photograph: Stu Forster/Getty Images