Williams attended college at the University of Alabama under Mark Gottfried. In 2002 as a freshman, he started every game at point guard. Williams averaged 10.4 points and 4.5 assists per game. His play helped lead the Crimson Tide to a 27–8 record, including a 17–0 home record, and the SEC regular-season championship. Williams and the Crimson Tide entered the NCAA tournament as a No. 2 seed, where they lost to Kent State 71–58 in the second round. Williams led the team in scoring and assists, averaging 16.4 points and 3.8 assists per game for the 2003 season, which ended in a first-round loss in the NCAA tournament to Indiana. He subsequently earned third-team All-SEC.
After two seasons, Williams decided to forgo his final two years at Alabama and enter the 2003 NBA draft.
Williams was selected by the Utah Jazz in the second round, 47th overall of the 2003 NBA draft. He averaged 5 points and 1.3 assists for the Jazz in his rookie season.
On August 8, 2004, the Milwaukee Bucks signed Williams, who was a restricted free agent, to an offer sheet. On August 21, the Jazz decided to not match the Bucks' offer.
Filling in for Bucks' injured starting point guard T. J. Ford, Williams averaged 10.2 points and 6.1 assists during the 2004–05 season. In his new role coming off the bench for the up-and-coming Bucks team, he showed a knack for clutch plays, making several game-winning shots in the 2005–06 season.
In the 2006 off-season, the Bucks traded Ford to the Toronto Raptors for power forward Charlie Villanueva. This opened up a position in the starting lineup for Williams. In the first 19 games of the 2006-07 season, Williams averaged 15.6 points, 5.1 rebounds and 6.2 assists in nearly 35 minutes per game, all career highs.
In a December 20, 2006, Bucks game vs. the Miami Heat, Williams recorded his first career triple-double with 19 points, 11 rebounds and 10 assists.
Williams was a free agent in summer 2007, but decided to stay with the Bucks by signing a six-year, $52 million deal.
On August 13, 2008, Williams was traded to the Cleveland Cavaliers in a three-team, six-player deal involving the Cavaliers, the Milwaukee Bucks, and the Oklahoma City Thunder that also sent Cleveland's Joe Smith and Milwaukee's Desmond Mason to Oklahoma City and sent Cleveland's Damon Jones and Oklahoma City's Luke Ridnour and Adrian Griffin to Milwaukee. Upon his arrival, he changed his jersey number to #2 because his traditional #25 was already retired by former Cavalier Mark Price.
On February 10, 2009, Williams was chosen to replace forward Chris Bosh in the 2009 NBA All-Star Game. He was the second alternate choice, after Ray Allen, who replaced an injured Jameer Nelson. On February 11, Williams scored a then career high 44 points to go along with 7 assists against the Phoenix Suns.
During the 2008–09 season, Williams helped the Cavaliers reach a league-leading 66–16 record. The team went 39–2 at the Quicken Loans Arena.
After the departure of LeBron James, Williams became a very vocal member of the Cavaliers. Amidst trade rumors, Mo hinted on his Twitter account that he didn't wish to be traded. He also criticized the events surrounding LeBron's flight from Cleveland and even shot back at insults made to the Cavaliers by Miami Heat guard Dwyane Wade.
On November 14, 2010, Williams made his first buzzer beater as a Cavalier, to win the game 83-81 over his former team, the Milwaukee Bucks. It was a 15-foot shot over Brandon Jennings as time expired. He scored a total of 25 points in the game and was the team's leading scorer.
On February 24, 2011, Williams was traded to the Los Angeles Clippers along with Jamario Moon in exchange for Baron Davis and a first round pick, which ended up being the first pick in the 2011 NBA draft, Kyrie Irving. With the Clippers, Williams was immediately inserted into the starting lineup to play both guard positions, and was able to raise his averages in points-per-game and field goal percentage.
The following season, the Clippers traded for Chris Paul and claimed Chauncey Billups off waivers, making Williams the Clippers' new sixth man. He embraced the role and finished eighth in voting for NBA Sixth Man of the Year.
On June 29, 2012, Mo Williams was traded back to the Jazz in a 4 team deal that sent Lamar Odom to the Los Angeles Clippers and the Utah Jazz's trade exception to the Dallas Mavericks. The Clippers also sent their second round pick Furkan Aldemir to the Houston Rockets.
On August 8, 2013, Williams signed with the Portland Trail Blazers. On November 23, 2013, in a game against the Warriors, Williams was ejected along with teammate Wesley Matthews after getting involved in an altercation. He was subsequently suspended for one game. Williams injured his groin in game two of the Trail Blazers' second round play-off match-up against the San Antonio Spurs.
On July 30, 2014, Williams signed a one-year, $3.75 million contract with the Minnesota Timberwolves. On January 13, 2015, Williams scored a career-high 52 points on 19-of-33 shooting, breaking the franchise single-game scoring record set by Kevin Love and Corey Brewer by one point in a 110–102 win over the Indiana Pacers. This was just the third time in Williams' career that he scored more than 40 points in a game. He subsequently earned Western Conference Player of the Week honors for the week of January 12–18.
On February 10, 2015, Williams was traded, along with Troy Daniels and cash considerations, to the Charlotte Hornets in exchange for Gary Neal and a 2019 second-round draft pick. He made his debut for the Hornets on February 21 against the Oklahoma City Thunder, recording 24 points and 12 assists in a 110–103 loss. Williams continued to play well as he was named Eastern Conference Player of the Week for games played Monday, March 2 through Sunday, March 8. Williams, who led the Hornets to the NBA's only 4–0 record in the week, was previously named Western Conference Player of the Week on January 19 while playing for the Timberwolves, making him the first player to earn the honor in both conferences in the same season since the award was split into two conferences starting with the 2001–02 season. Over the four-game week, Williams averaged 19.5 points and 10.8 assists in 35.5 minutes played, while shooting .429 from the field (24-56), .375 from beyond the three-point line (9-24) and .913 from the free throw line (21-23). The only Eastern Conference player to average double figures in assists, he also posted an assist-to-turnover ratio of 4.78.
On July 10, 2015, Williams signed a two-year, $4.3 million contract with the Cleveland Cavaliers, returning to the franchise for a second stint and reuniting him with LeBron James. In his first game for the Cavaliers since 2011, Williams recorded 19 points and 7 assists, filling in for the injured Kyrie Irving as a starter in the team's season opening loss to the Chicago Bulls on October 27. Over the Cavaliers' first 23 games of the season, Williams played in 20 of them and started in 14. Over that stretch, he averaged 13.0 points and 4.1 assists in 27.6 minutes per game, as he shared the point guard role with Matthew Dellavedova. However, upon the return of Kyrie Irving from injury on December 20, Williams' role decreased and his minutes were drastically reduced, partially due to suffering from his own injury, a torn ligament in his right thumb. On January 12, he was excused by the team from their game in Dallas to tend to a personal matter. He started seeing more minutes in early February, but following the All-Star break, he appeared in just one game between February 18 and March 24 due to swelling in his left knee after being diagnosed with chondromalacia. He made his return to the line-up on March 26 against the New York Knicks, scoring eight points in 13 minutes off the bench. However, in early April, he began experiencing discomfort and increased soreness in his left knee, forcing him to miss more time. Williams received limited playing time during the Cavaliers' playoff run, a run that saw the team reach the 2016 NBA Finals with a 12–2 record. Williams made his first appearance in the NBA Finals during a Game 1 loss to the Golden State Warriors. Despite the Cavaliers going down 3–1 in the series following a Game 4 loss, they went on to win the series in seven games to become the first team in NBA history to win the championship after being down 3–1.
On June 14, 2016, before the end of the 2016 NBA Finals, Williams exercised his player option with the Cavaliers for the 2016–17 season. Williams originally declared that the 2016–17 season would be his last, but on September 26, 2016, he announced his intentions to retire from the NBA. However, he never officially signed retirement papers and instead remained on the Cavaliers' roster. Not being a rotation player in 2015–16 for the first time had been the most challenging time of Williams' career, and while the departure of Matthew Dellavedova in the 2016 off-season opened a spot at point guard, the Cavaliers drafted Kay Felder in the 2016 draft, which would have left Williams a third-string point guard for a second straight season. Williams did not join the playing group for the 2016–17 season and in October 2016, he underwent surgery on his left knee. In January 2017, rumors began to surface of Williams being a possible trade piece for the Cavaliers.
On January 7, 2017, Williams was traded, along with Mike Dunleavy Jr. and a future first-round draft pick, to the Atlanta Hawks in exchange for Kyle Korver. He was later shipped to the Denver Nuggets alongside cash considerations on January 18, 2017 in exchange for the rights to Cenk Akyol; he was immediately waived by the Nuggets upon being acquired. Two days later, he was claimed off waivers then immediately waived by the Philadelphia 76ers. The 76ers reportedly made the claim in order to get $2.2 million closer to the salary floor while preventing the Nuggets from doing so after Denver acquired Williams in a trade with the Hawks. He was later claimed and waived by the Nuggets on January 23 for a similar reason.