Bangladesh, needing victory to level the series, reached 409 for eight wickets in their first innings at stumps on the third day, still trailing the visitors by 178 runs.
Mahmudullah (30) and Al-Amin Hossain (three) remain at the crease for the hosts.
Resuming at 86 for one wicket, opener Shamsur (106) and number three Kayes (115) batted through the first session to launch a gritty reply from Bangladesh, who had been battered by a triple-century by Kumar Sangakkara in Sri Lanka's first innings.
The 25-year-old Shamsur, in his second Test, got to his hundred first with a boundary through cover off Sri Lanka captain Angelo Mathews.
Kayes, 27, playing his first Test for over two years, survived some nervous moments in the nineties before cutting paceman Suranga Lakmal to the point boundary to complete his century.
Kithuruwan Vithanage, at point, first dropped an easy catch off Ajantha Mendis with the left-hander on 95 and then gleefully accepted another later in the over, only to find out that the bowler had overstepped for a no-ball.
Both Shamsur and Kayes played casual shots to gift their wickets to Mendis after a 232-run partnership.
Off-spinner Dilruwan Perera then dismissed Mominul Haque (13) for the first of his three wickets as Bangladesh wobbled at 259 for four.
The innings was stabilised by a 60-run stand for the fifth wicket between all-rounder Shakib Al Hasan (50) and captain Mushfiqur Rahim (20), before both were dismissed by Perera with Bangladesh still shy of the follow-on mark at 350 for six.
Nasir Hossain (42) added a vital 46 runs with Mahmudullah to take Bangladesh past the follow-on figure of 387 but edged Mendis to Dinesh Chandimal behind the stumps with just over three overs left in the day.
Mendis then claimed his fourth scalp the next ball, trapping Sohag Gazi leg before, but was denied the hat-trick when the umpire turned down another lbw appeal against A-Amin.
Scorecard
Sri Lanka (1st innings): 587
Bangladesh (1st innings): (overnight 86-1)
Tamim Iqbal b Lakmal 0
Shamsur Rahman b Mendis 106
Imrul Kayes b Mendis 115
Mominul Haque lbw b Perera 13
Shakib Al Hasan c Karunaratne b Perera 50
Mushfiqur Rahim c Silva b Perera 20
Nasir Hossain c Chandimal b Mendis 42
Mahmudullah not out 30
Sohag Gazi lbw b Mendis 0
Al-Amin Hossain not out 3
Extras: (b-8, lb-1, nb-21) 30
Total: (eight wickets; 115 overs) 409
Fall of wickets: 1-0, 2-232, 3-252, 4-259, 5-319, 6-350, 7-396, 8-396.
Bowling: Lakmal 23-5-68-1, Pradeep 15-2-96-0 (nb-13), Mendis 27-2-84-4 (nb-8), Perera 39-4-119-3, Mathews 11-1-33-0.
Image: Imrul Kayes
Photograph: Clive Mason/Getty Images
Sangakkara's triple ton puts Sri Lanka in command
Sri Lanka crush Bangladesh with a day to spare
Stylish centurion Sangakkara sparkles for Sri Lanka in 2nd Test
Sri Lanka well-placed after seamers dismiss Bangladesh cheaply
Kaushal Silva hits maiden Test ton as Lanka swell lead vs Bangladesh