Professionista dal 1997 al 2013, è stato uno dei migliori scalatori italiani del periodo, dimostrandosi competitivo anche sul passo, in volata e a cronometro, in una carriera quasi ventennale. Nel 2000, in maglia Mercatone Uno, ha ottenuto la più importante vittoria in carriera, aggiudicandosi l'ottantatreesima edizione del Giro d'Italia.
Dal 2014, dopo l'addio alle corse, diventa commentatore tecnico, per il ciclismo su Rai Sport, ed inoltre è direttore sportivo per team professionistici.
Carriera Gli esordi nel ciclismo Corridore tenace, iniziò a correre all'età di 10 anni nella Polisportiva Besanese, squadra di Besano, il suo paese di origine, cui rimase legato fino al secondo anno della categoria Allievi. Passò dunque nel Pedale Sommese, altra squadra della provincia di Varese, gareggiando per l'ultimo anno tra gli allievi e nel primo tra gli Juniores, senza compagni di squadra in quanto il Gruppo Sportivo Pedale non allestì una formazione per quella categoria. Nel secondo anno come Juniores gareggiò nella Besnatese Rollmar Ambrosio, vincendo due classiche da scalatori, il campionato provinciale con l'arrivo sul Brinzio e la Cirié-Pian della Mussa, e iniziando a confrontarsi con le gare a tappe, in particolare il Giro della Basilicata.
Nel 1992 passò dilettante nella Polisportiva Coop Corsico insieme all'altro varesino Daniele Nardello e, pur non ottenendo vittorie, corse un ottimo Giro della Valle d'Aosta, classificandosi diciannovesimo e confermando la propensione per le gare a tappe già mostrata negli anni precedenti. L'anno successivo si trasferì alla Brunero Bongioanni per poi passare, due anni più tardi nel 1995, alla Resine Ragnoli di Brescia, diretta da Pierino Gavazzi. Nella formazione bresciana iniziò a lavorare più seriamente e si impose in diverse gare adatte agli scalatori, con arrivo in volata, come la Villa d'Almè-Sedrina.
Nel 1996 fu istituita la categoria Under-23, il che gli impedì di partecipare a diverse gare come il Giro d'Italia dilettanti, quindi si concentrò sulla Settimana Ciclistica Bergamasca nella prima parte della stagione e sul Giro della Valle d'Aosta nella seconda. Sfruttando la forma trovata in quest'ultimo, riuscì a vincere il Piccolo Giro di Lombardia, la sua vittoria più importante tra i dilettanti. In seguito alla vittoria anche della Sacile-Col Alt, il 17 ottobre Giuseppe Martinelli gli offrì un contratto da professionista nella Mercatone Uno.
1997-2000: gli anni alla Mercatone Uno e la vittoria del Giro Nel 1997 Garzelli arrivò dunque nella squadra che lo vedrà protagonista per i successivi quattro anni insieme a Marco Pantani; a fargli da chioccia fu Massimo Podenzana. Dopo le prime gare stagionali e l'ambientamento nella nuova categoria, fu iscritto al Giro d'Italia con l'obiettivo di aiutare Pantani in salita e accumulare ulteriore esperienza. Proprio al Giro dimostrò predisposizione per le gare a tappe e, rimanendo libero di fare la sua corsa dopo il ritiro di Pantani in seguito alla caduta nella Mondragone-Cava dei Tirreni, iniziò a risalire la classifica raggiungendo la nona posizione finale, dopo l'ottima terza settimana in cui conquistò anche un terzo posto nella quattordicesima tappa, Racconigi-Cervinia, dietro a Ivan Gotti e a Pavel Tonkov. Si riconfermò al Tour de Suisse, conquistando il secondo posto nella tappa con arrivo a Kandersteg dietro a Jan Ullrich, l'ottava posizione finale nella classifica generale e vincendo la classifica finale di miglior scalatore.
Nel 1998 partì con l'obiettivo di riconfermarsi al Giro d'Italia, poi vinto da Pantani, ma cadde nella diciannovesima tappa, andando fuori classifica. Si presentò al successivo Tour de Suisse con l'intenzione di vincerlo, nonostante la presenza di campioni come Ullrich, Jalabert, Casagrande e Bjarne Riis. Garzelli dominò la corsa, arrivando quarto nel primo arrivo in salita, terzo in volata a Varese e primo nei due tapponi alpini con arrivo a Lenzerheide; indossò la maglia di leader che portò fino a Berna, vincendo anche classifica a punti e combinata.
Nel 1999 la volontà della Mercatone di essere competitiva anche in altre gare lo portò ad essere già in un ottimo stato di forma per le prime corse della stagione. Ottenne il terzo posto finale nella Tirreno-Adriatico, il quarto in volata alla Milano-Sanremo e vinse, sempre allo sprint, il Gran Premio Miguel Indurain e la quarta tappa alla Vuelta al País Vasco, confermandosi competitivo anche in questo tipo di arrivi. Durante il Tour de Romandie, classica preparazione al Giro d'Italia, un infortunio al ginocchio destro lo costrinse al ritiro e a recarsi al Giro con una scarsa condizione fisica, che lo limitò nelle tappe più dure. Garzelli si ritirò con tutta la squadra dopo la squalifica di Pantani a Madonna di Campiglio. Andò per la prima volta al Tour de France, ma la stanchezza accumulata nel corso della stagione non lo portò oltre il trentaduesimo posto nella classifica generale finale.
L'anno successivo la preparazione fu programmata con l'unico obiettivo del Giro d'Italia. Nelle prime gare della stagione Garzelli vinse una tappa, la quarta, alla Settimana Ciclistica Bergamasca. La prima parte del Giro fu controllata da Casagrande, che vestì la maglia rosa dalla nona alla diciannovesima tappa. Garzelli trionfò nella diciottesima con arrivo in quota a Prato Nevoso, grazie anche al prezioso aiuto di Pantani, conquistando la sua prima vittoria di tappa al Giro. Nella cronometro individuale del Sestriere, penultimo arrivo della corsa rosa, il leader Casagrande crollò, consegnando al varesotto la maglia rosa e la vittoria della corsa. Disputò successivamente il Tour de Suisse, riuscendo però a vincere solamente l'ottava tappa con arrivo a La Punt. Riprese a gareggiare nella seconda parte dell'anno, ma una caduta e un'irritazione al soprassella lo costrinsero a terminare la stagione anticipatamente.
2001-2002: gli anni alla Mapei-Quick Step e la squalifica Al termine del 2000 decise di abbandonare la Mercatone Uno, per evitare di dover fare ancora da gregario e poter gareggiare da leader, e si accasò alla Mapei-Quick Step di Giorgio Squinzi dal 2001. Si preparò ancora con l'obiettivo del Giro, gareggiando nelle classiche spagnole, Setmana Catalana e Vuelta al País Vasco, dove vinse la quinta tappa, prima vittoria con la nuova divisa.
Vinse in seguito il Gran Premio Industria e Artigianato di Larciano. Si presentò dunque al Giro d'Italia con l'intenzione di riconquistare la maglia rosa: si classificò terzo nella quarta tappa da Potenza a Montevergine di Mercogliano, ma nei giorni seguenti fu vittima di un attacco influenzale, che lo costrinse al ritiro al termine della tredicesima tappa del Giro, poi vinto da Simoni. Dopo il Tour de Suisse, in cui vinse la settima tappa, affrontò il Tour de France in cui mostrò molte difficoltà sulle tappe alpine, ma si riprese sui Pirenei e si portò al decimo posto in classifica. Terminò la "Grand Boucle" al quattordicesimo posto.
Nel 2002 iniziò la preparazione ancora con le classiche spagnole, tenendo sempre come obiettivo il Giro. Il 21 aprile conquistò un grande secondo posto nella Liegi-Bastogne-Liegi, gara valida per la Coppa del Mondo: attaccò sulla Côte de Vauche, a 60 km dall'arrivo, insieme a nove uomini, tra cui il compagno di squadra Paolo Bettini, e tirò su tutte le salite. I due italiani rimasero soli sul traguardo ma, giocandosi la vittoria in volata, Bettini era il più veloce ed ebbe la meglio. Conquistò la prima vittoria della stagione nel Gran Premio Città di Camaiore battendo Figueras e Casagrande.
L'ottantacinquesimo Giro d'Italia iniziò da Groninga nei Paesi Bassi. La prima vittoria arrivò già nella seconda tappa, con traguardo a Liegi, dove il 21 aprile era arrivato secondo nella classica di Coppa: attaccò sulle ultime côtes e batté in volata Francesco Casagrande, sfilando anche la maglia rosa a Mario Cipollini. Il 13 maggio conquistò la seconda vittoria di tappa, battendo Simoni e Casagrande all'arrivo in quota di Limone Piemonte.
Quattro giorni dopo, venerdi 17 maggio, arrivò la notizia della positività a un diuretico, il Probenecid, risultata nel test antidoping seguito alla vittoria di Liegi. Nonostante sostenesse di non aver mai assunto tale sostanza e si facesse l'ipotesi di un probabile inquinamento alimentare, le controanalisi confermarono la presenza di 20 nanogrammi del diuretico nel suo sangue e fu costretto così ad abbandonare il Giro il 21 maggio. .
2003-2004: le due stagioni alla Vini Caldirola
Tornò alle gare il 24 aprile 2003 con la maglia della Vini Caldirola, dominando la volata della prima tappa del Giro del Trentino, la Arco-Moena di 170,5 km. Giunse secondo il giorno successivo a Ronzone e terminò il Giro al secondo posto a 9 secondi da Gilberto Simoni. Il 10 maggio iniziò l'ottantaseiesimo Giro d'Italia e subito si impose vincendo la terza tappa, Policoro-Terme Luigiane con arrivo in salita, staccando di 2 secondi Casagrande. Sette giorni dopo conquistò anche la Avezzano-Terminillo, battendo Simoni e Noé. Sul secondo posto che ottenne nella classifica generale finale pesò la caduta nella discesa del Colle di Sampeyre, che gli fece perdere 6 minuti.
Al Tour del centenario fu pesantemente limitato da problemi respiratori che lo costrinsero al ritiro al termine della tappa con arrivo all'Alpe d'Huez. Riuscì comunque a vincere il premio Henry Desgrange, passando per primo in cima al Colle del Galibier. Il 19 dicembre 2003 sposò Marta, ragazza spagnola conosciuta a Valencia.
Nel 2004 puntò ancora tutto sul Giro d'Italia, in quanto la Vini Caldirola non era tra le prime 18 formazioni al mondo e dunque non avrebbe avuto la possibilità di partecipare al Tour e alle altre grandi corse. Iniziò la preparazione ancora in Spagna, ma l'inverno fu segnato dalla morte dell'amico Marco Pantani. Dopo la Settimana Catalana, corse la Vuelta a Aragón: giunse secondo nella prima tappa dietro a Denis Men'šov e riuscì a conquistare la maglia amarillo finale grazie al terzo posto nell'ultima tappa.
Dopo aver fallito alla Liegi-Bastogne-Liegi, vinse la seconda tappa del Tour de Romandie a Romont. Si presentò quindi al Giro d'Italia dove mostrò una scarsa condizione nelle prime due settimane, per poi rifarsi nella terza, facendo la differenza nella penultima tappa da Bormio alla Presolana. Attaccò sul Mortirolo, cima dedicata a Pantani, insieme a Simoni e con il trentino si lanciò in una fuga di 80 km, battendolo in volata dopo aver scalato Vivione e Presolana. Terminò al sesto posto nella classifica generale.
Nella seconda parte della stagione gareggiò per conquistarsi la maglia della Nazionale, arrivando undicesimo alla Vuelta a España. Fu quindi convocato da Franco Ballerini per la gara in linea del 6 ottobre del Campionato del mondo di Verona. Mancò però l'importante occasione e non riuscì a proporsi dopo l'infortunio che bloccò Bettini, ritirandosi al diciassettesimo giro.
2005-2006: il passaggio alla Liquigas e il ProTour
Con la nascita dell'UCI ProTour, che limitava la partecipazione alle gare più importanti alle venti maggiori squadre, scelse di passare alla Liquigas-Bianchi insieme al team manager Roberto Amadio, e il suo obiettivo stagionale fu ancora una volta il Giro d'Italia. Dopo un buon Tour de Romandie, si presentò al Giro: conquistò il terzo posto nella terza tappa ma, dopo la caduta nell'ultimo chilometro della settima tappa a Pistoia, fu costretto a ritirarsi cinque giorni più tardi a causa di un esteso ematoma che provocò un versamento di sangue nel rene destro.
Dopo un periodo di riposo e la lenta ripresa, partecipò al Tour de France, dove non riuscì a essere competitivo classificandosi trentaduesimo nella classifica generale finale. Acquisì comunque un'ottima forma per la parte finale della stagione. Arrivò infatti in agosto la prima vittoria, il 16 sul traguardo di Campione d'Italia della Tre Valli Varesine. La stagione terminò con il secondo posto nel Trofeo Melinda.