Afridi helped Pakistan recover from a struggling 7-120 to 200 all out with a 65-ball 75 before he derailed Sri Lanka by taking 5-35 to dismiss them for 174 in 45.2 overs, giving his team an unassailable 3-1 lead in the five-match series.
The victory leaves the fifth and final game at Abu Dhabi on Wednesday as inconsequential.
The sides will also play a Twenty20 international at Abu Dhabi on Friday.
Mahela Jayawardene and Kumar Sangakkara had set Sri Lanka on course for a comfortable win with a 102-run fourth-wicket stand after Sri Lanka were struggling at 3-53 with Upul Tharanga (16) and Tillakaratne Dilshan (11) gone by the eighth over.
With 46 needed for victory Sangakkara, who hit six boundaries during his 103-ball knock, was bowled by Afridi for 58 and Saeed Ajmal accounted for Angelo Mathews (nought) in the next over.
That triggered a collapse in which Sri Lanka lost their last seven wickets for 19 runs.
It included all of Afridi's wickets in a sensational display of leg-spin bowling. The 31-year-old thus became the only man in one-day cricket to hit a half century and take five wickets in the same match on two occasions.
Jayawardene, who made 55, fell in the 44th over which left Sri Lanka with no chance to get the win they were seeking.
Afridi said he was happy to play a lead role.
'I like to perform like this in every match,' said Afridi, playing after a six month gap which saw him retire from international cricket in protest over being sacked as one-day captain.
'Sri Lanka were in a winning position but captain (Misbah-ul Haq) said we needed just one wicket and I was lucky that I got Sangakkara out.'
Sri Lankan captain Dilshan said the collapse was 'unbelievable.'
Earlier Afridi hit four boundaries and three sixes to lift his team from a precarious 120 for 7 to 200 in 49.3 overs.
Afridi added an invaluable 61 runs for the eighth wicket with tail-ender Saeed Ajmal who finished with 20.
The swashbuckling Afridi hit spinner Seekkuge Prasanna over extra cover for a six to reach his 31st half-century - his first in 15 innings - before hitting the same bowler for two boundaries and a six to notch up 19 in the 43rd over.
He finally fell, caught behind off paceman Thissara Perera, in the next over.