Operator overloading allows user-defined types to have special meanings applied to operators like + and *. It is a form of polymorphism that allows operators to work on custom data types like user-defined objects in the same way they work on built-in types. To overload an operator, a programmer defines operator functions that specify the behavior for that operator when used on a class. These functions can be member functions or non-member functions. Certain operators cannot be overloaded and rules govern the number of arguments for operator functions.