Barcelona lyckades vända underläge två gånger om, och därmed ta matchen till förlängning.
Väl där orkade man inte med ännu en vändning när Federico Valverde sköt Real till final.
Vinicius Junior hade gett Real ledningen efter ett otagbart skott i nättaket i den 25:e matchminuten. Men efter flera chanser från Barcelona kunde Luuk de Jong utjämna med knappt fem minuter kvar till paus.
Även i den andra halvleken var det huvudstadslaget som började bäst, men det dröjde till den 72:a minuten innan Karim Benzema gav ledningen åter till de vitklädda.
Och under de följande elva minuterna såg det ut som att han hade skjutit Real Madrid hela vägen till finalen.
Men med sju minuter kvar av ordinarie speltid mötte Ansu Fati ett perfekt inlägg från Jordi Alba och utjämnade matchen med en precis nick.
I förlängningen var det sedan Real som var starkare och Federico Valverde kunde säkra segern genom att skicka in 3–2 åtta minuter in i förlängningen.
I den andra semifinalen möts Atlético Madrid och Athletic Bilbao.