The contest went down to the last ball of the final over, Windies captain Jason Holder unable to score more than a single off Nuwan Pradeep (1-65) to finish on 329-9, agonisingly short of their target.
They must now overcome hosts Zimbabwe on Friday to set up a re-match against Sri Lanka in the tournament’s decider two days later.
Put in to bat after losing the toss, Niroshan Dickwella and Kusal Mendis fell just short of centuries as Sri Lanka posted 330-7 from their 50 overs at Queens Sports Club.
Dickwella and Mendis both made 94, the former missing out on his first ODI ton when he was trapped lbw by Holder (3-57).
Mendis, having entertained with five sixes and seven boundaries in his pacey 73-ball knock, departed five overs later, edging a quicker Ashley Nurse (1-58) delivery to wicketkeeper Shai Hope.
Earlier, despite the loss of fellow opener Kusal Perera for seven, Dhananjaya de Silva (58) had got Sri Lanka off to a good start, only to fall caught and bowled to Kraigg Brathwaite (1-56), Upul Tharanga (26) and Sachith Pathirana (24) making valuable late contributions.
West Indies’ run chase was superbly anchored by Evin Lewis, who found the ropes 15 times and also plundered four maximums as he top-scored in the match with 148.
In a fitting metaphor for the innings, Lewis was run out as a consequence of captain Holder’s carelessness and it was a similar story for the rest of the top order.
Johnson Charles (26), Brathwaite (16) and Hope (25) all failed to build on starts, with the latter and Jonathan Carter (6), in addition to Lewis, both the victims of run outs.
Holder at least did his best to make amends for his earlier error, battling to 45 not out as the tail came and went around him.
Sulieman Benn was almost an unlikely hero for Windies, wearing sunglasses as he arrived at the crease in the 49th over and promptly hitting a six that gave his team a realistic chance of victory, before holing out to Dhananjaya at deep cover off the penultimate delivery.
Holder was then unable to find the boundary he needed, as Pradeep conjured a decisive yorker. (Courtesy Omnisport)