Pakistan, who needed to win by 65 runs in their final Super Eights match to pip New Zealand on net run rate, won by only five after scoring 212-8 with Sri Lanka just falling short on 207-6.
Sahibzada Farhan hit a 60-ball century for Pakistan, his second of the tournament, to take his side to their highest total in any T20 World Cup.
Pakistan needed to keep Sri Lanka down to 147 or fewer, but Pavan Rathnayake hit 58 and captain Dasun Shanaka struck an unbeaten 76 off just 31 balls to snuff out Pakistan hopes of advancing
"When I lost the toss, it was always going to be challenging (bowling second) because of the dew," said Pakistan captain Salman Ali Agha.
"Then it was a very good pitch and restricting them below 148 was going to be a challenge. But we tried.
"I think if I won the toss then it could have been a different story."
After a thrilling chase, Sri Lanka needed six off the last ball but Shanaka failed to connect after hitting three of his eight sixes in the final over as he took 22 off Shaheen Shah Afridi.
"It was that close of a game, I could have finished it. But, yeah, unfortunate. Well bowled to Shaheen," said Shanaka.
The result puts New Zealand through to a likely meeting with South Africa in Kolkata on Wednesday for a place in the final.
Spinner Abrar Ahmed was the pick of the Pakistan bowlers with 3-23 in his four overs.
After Pakistan were asked to bat first, Farhan followed his group-stage century against Namibia with another ton to become the first player to score two hundreds in the same T20 World Cup.
Fellow opener Fakhar Zaman cracked 84 off 42 balls.
Farhan scored five sixes and nine fours as he took his aggregate for the tournament to 383 runs, a T20 World Cup record, passing India's Virat Kohli's 319 in 2014.
Farhan and Zaman put on an opening stand of 176 in 15.5 overs. Zaman hit four sixes and nine fours.
Farhan pushed Shanaka for a single to complete his century off 59 balls before being dismissed by Dilshan Madushanka in the final over.
Madushanka was the best Sri Lankan bowler with 3-33.
Pakistan's previous highest at a T20 World cup was the 201-5 they made against Bangladesh in Kolkata in 2016.