Grant Elliott hit a six off the penultimate delivery to secure New Zealand's place in the World Cup final with a thrilling four-wicket win, with only 1 ball to spare.
Elliott smashed Dale Steyn into the stands as he hit an undefeated 84 to earn a place in Sunday's final against Australia or defending champions India.
Brendon McCullum made a 26-ball 59 and Corey Anderson 58 to help the hosts reach their rain-adjusted target of 298 after South Africa had made 281-5 batting first in a match reduced to 43 overs a side.
For South Africa, Faf de Plessis made 82, AB de Villiers was not out 65, while David Miller smashed an 18-ball 49.
New Zealand’s Grant Elliot was adjudged the player of the match.