Tamim made 133 off 217 before retiring hurt due to a muscle cramp as the hosts reached 3-318 on Tuesday in reply to Sri Lanka's 397.
Mushfiqur Rahim and Liton Das put on a 98-run unbroken stand to keep Bangladesh in a commanding position.
Liton is on 54 while Mushfiqur reached 53 at stumps, with Bangladesh cutting the first innings deficit to 79 runs after Angelo Mathews scored a brilliant 199 for the visitors.
Tamim, who recorded 15 fours, aggressively took on the Sri Lankan bowlers after Bangladesh resumed on 0-76, hitting Vishwa Fernando for consecutive boundaries in the first two balls faced.
Fernando, who was hit on the helmet during Sri Lanka's innings, went for a medical checkup after bowling four overs in the morning.
He was later ruled out of the match and Kasun Rajitha replaced him as a concussion sub.
Tamim raised his 32nd Test half-century off just 73 balls, cutting offspinner Ramesh Mendis for a boundary past point.
Mahmudul was restrained but never hesitated to punish the loose deliveries.
He reached his half-century from 112 deliveries, flicking paceman Asitha Fernando (1-55) through mid-wicket. Mahmudul was on 51 when he got a reprieve in Asitha Fernando's next over, with Lasith Embuldeniya dropping a catch at fine leg.
But Mahmudul (58) didn't survive long, hitting a delivery of Asitha that went down the leg side to give the visitors their first breakthrough.
Tamim, however, continued to attack and brought up his century off 162 balls, flicking Asitha for a single through midwicket.
Rajitha (2-17) then troubled Bangladesh for a brief period and got his reward, dismissing Najmul Hossain (1) and captain Mominul Haque (2).
Tamim and Mushfiqur Rahim helped Bangladesh regain control but Sri Lanka could have removed Tamim for 114 had Dhananajaya de Silva not dropped him at slip after Tamim went for an expansive drive.
Tamim retired hurt on 133 after suffering cramp, but Liton and Mushfiqur kept at it to further frustrate the bowlers.