United Rugby Championship semi-final
Bulls: (10) 25
Tries: Goosen, Petersen (2) Cons: Goosen (2) Pens: Goosen (2)
Leinster: (7) 20
Tries: Lowe, Doris Cons: Byrne (2) Pens: Byrne (2)
Leinster were narrowly beaten by Bulls in a titanic encounter at Loftus Versfeld Stadium in their United Rugby Championship [URC] semi-final.
Leo Cullen's side trailed 10-7 after a scrappy first half, with Johan Goosen cancelling out James Lowe's opening try.
Sergeal Petersen crossed twice, in between a Caelan Doris try, as the hosts survived late Leinster pressure to win a bruising clash.
Jake White's Bulls will face Glasgow in the competition's decider on Saturday, 22 June in Pretoria after the the Scottish side beat reigning champions Munster 17-10.
Leinster have now gone three seasons since their last trophy win.
Many of Leinster's squad had not played a game in South Africa before the game in Pretoria, and they took some time to get up to speed in the searing heat.
After a tense first 15 minutes, the Bulls began to assert their dominance and the game burst into life when Devon Williams had a try disallowed by the TMO.
Williams raced over in the corner after being found by a great pass from Willie le Roux, but it was soon chalked off after a needless foul by Marco van Staden on Ross Byrne in the build-up.
It was a let-off for Leinster, who then squandered a good chance to take the lead at the other end as Byrne was wayward from the tee with his penalty.
Leo Cullen's side took advantage of Sergeal Petersen being sent to the sin-bin for 10 minutes for a deliberate knock-on.
After a strong maul, Byrne found Lowe out wide with an unorthodox pass and he touched down for the game's first try.
Byrne made amends for his penalty miss by nailing his conversion.
Their lead would last just six minutes however, with Bulls' pressure eventually resulting in a try.
Goosen darted through Leinster's defensive line and dotted down before he kicked the conversion to bring the scores level.
A late penalty from Goosen, after Leinster's scrum caved in, then sent Bulls in at the break leading.
Leinster have tended to save their good performances for second halves of games, but it was Bulls who would come flying out of the traps as they extended their lead soon after the restart.
A swift move resulted in kicking forward to the onrushing Petersen with the ball bouncing nicely for him to touch down.
Goosen was spot on from the tee to stretch their advantage to 10 points.
Leinster refused to lie down however and found a route back into the game with a try on 50 minutes.
After a number of attempts to cross the line were repelled, they won a penalty and opted to tap and go and were rewarded for their patience.
Doris crashed over with Byrne kicking the conversion and then converting a penalty to bring Leinster level and set up an intriguing finale.
Goosen and Byrne exchanged penalties as the two teams became reliant on the accurate kicking of their two 10s as the clock ticked towards the red.
Petersen produced a moment of individual quality for Bulls' third try, beating Ciaran Frawley to a high box-kick, evading a challenge and slamming down.
Goosen was uncharacteristically off target from the tee.
Leinster piled on some late pressure, with one move including 22 phases, but they were unable to break down a stubborn Bulls defence who held on for victory.
Bulls: Willie Le Roux; Sergeal Peterson, David Kriel, Harold Vorster, Devon Williams; Johan Goosen, Embrose Papier; Gerhard Steenkamp, Johan Grobbelaar, Wilco Louw; Ruan Vermaak, Ruan Nortje (capt); Marco van Staden, Elrigh Louw, Cameron Hanekom
Replacements: Akker van der Merwe, Simphiwe Matanzima, Francois Klopper, Reinhardt Ludwig, Nizaam Carr, Keagan Johannes, Chris Smith, Cornel Smit
Leinster: Jimmy O'Brien; Jordan Larmour, Garry Ringrose, Robbie Henshaw, James Lowe; Ross Byrne, Jamison Gibson-Park; Andrew Porter, Dan Sheehan, Tadhg Furlong; Joe McCarthy, James Ryan (capt); Ryan Baird, Josh van der Flier, Caelan Doris
Replacements: Ronan Kelleher, Cian Healy, Michael Ala’alatoa, Ross Molony, Jack Conan, Luke McGrath, Ciarán Frawley, Jamie Osborne.