The men from Cape Town, who led 22-21 at the break, outscored their hosts by six tries to five in a game in which both teams employed expansive tactics.
Tries from Cheslin Kolbe, Sikhumbuzo Notshe, Dillyn Leyds, Siya Kolisi, Damian Willemse and Seabelo Senatla proved too much for the Bulls who scored through Jason Jenkins, Duncan Matthews, Piet van Zyl and a Jesse Kriel brace.
The Bulls had their chances but paid the ultimate price for missing too many first time tackles.
The home side took the early lead with a great team try. Their mobile forwards did excellent work around the fringes with RG Snyman, Jannes Kirsten and Abongile Nonkontwana all making good ground before Nonkontwana popped the ball up off the ground to Jan Serfontein who broke but was brought down inches short. Jenkins burst over from close range with a powerful pick and drive as Tian Schoeman made no mistake with the conversion.
The Stormers hit back immediately via superb individual brilliance from Kolbe. The diminutive speedster cut inside and ducked and dived his way past six Bulls defenders before rolling and dotting down. Willemse added the extras to level matters at 7-7 after 10 minutes.
Soon afterwards, the Stormers took the lead. Jano Vermaak made the initial break but was brought down by an ankle tap. The ball was recycled and this time Leyds did well to break the line. From the ruck, Vermaak went right to Damian de Allende who put Notshe through a gap as the flanker crossed the whitewash to dot down.
But it was the Bulls who responded this time to restore parity on the scoreboard. The home side’s backline combined superbly to set Matthews free on the left touchline, with the winger racing through to dot down.
A few minutes later, Matthews turned provider as he ran a wonderful line before passing on his inside for Kriel to have a clear run to the line.
Once again, the lead switched hands as the Stormers hit back. It all started from Senatla's mesmerising break but it looked as if he had butchered the opportunity opting to hold on to the ball when it would have been wiser to go out wide on the overlap.
However, from the recycled ball, Vermaak went out right to Willemse who exploited the space ,putting Pieter-Steph du Toit through a gap and the big lock showed a subtle sleight of hand with his offload finding Leyds who was not going to be halted with that pace and dotted down under the posts. Willemse converted as the away side took a one point lead (22-21) into half-time.
The home side went down to fourteen men when Conraad van Vuuren was yellow-carded for a hight tackle. The Stormers capitalised on their numerical advantage when Kolisi burst over from close range after a series of powerful carries.
The visitors extended their lead thanks largely to a piece of Leyds-inspired magic. The skilful fullback once again managed to wriggle his way through a gap before offloading to Willemse who somehow managed to evade the tackle of two Bulls defenders in crossing the whitewash.
But the Bulls hit back with two converted tries in quick succession. The first came from a sniping break from replacement scrumhalf Piet van Zyl who went all the way himself. The second came from an errant Stormers pass which Kriel pounced upon and ran from inside his own half to score under the posts, cutting the deficit to one at 34-33.
But Senatla put the game beyond reach with a minute to go after he collected Leyds' chip kick to make it 41-33.
The Stormers will host the Chiefs in next weekend's quarter-finals at Newlands, while the Bulls end a miserable season which saw them win only four from 15 games.
Tries: Jason Jenkins, Duncan Matthews, Jesse Kriel (2), Piet van Zyl
Conversions: Tian Schoeman (4)
Tries: Cheslin Kolbe, Sikhumbuzo Notshe, Dillyn Leyds, Siya Kolisi, Damian Willemse, Seabelo Senatla
Conversions: Willemse (3), Kolbe
15 Warrick Gelant, 14 Travis Ismaiel, 13 Jesse Kriel, 12 Jan Serfontein, 11 Duncan Mathews, 10 Tian Schoeman, 9 Rudy Paige, 8 Jannes Kirsten, 7 Abongile Nonkontwana, 6 Shaun Adendorff, 5 RG Snyman, 4 Jason Jenkins, 3 Conraad van Vuurren, 2 Adriaan Strauss (captain), 1 Pierre Schoeman
Substitutes: 16 Jaco Visagie, 17 Trevor Nyakane, 18 John-Roy Jenkinson, 19 Ruben van Heerden, 20 Ruan Steenkamp, 21 Piet Van Zyl, 22 Tony Jantjies, 23 Burger Odendaal
15 Dillyn Leyds, 14 Cheslin Kolbe, 13 EW Viljoen, 12 Damian de Allende, 11 Seabelo Senatla, 10 Damian Willemse, 9 Jano Vermaak, 8 Nizaam Carr, 7 Sikhumbuzo Notshe, 6 Siya Kolisi (captain), 5 Pieter-Steph du Toit, 4 Eben Etzebeth, 3 Frans Malherbe, 2 Bongi Mbonambi, 1 JC Janse van Rensburg.
Substitutes: 16 Ramone Samuels, 17 Steven Kitshoff, 18 Frans van Wyk, 19 Chris van Zyl, 20 Juarno Augustus, 21 Justin Phillips, 22 Juan de Jongh, 23 Dan Kriel