As to3m says, this is often done in programming language interpreters.
If most objects in your language were heap allocated and you want to store a small integer you would allocate a new object on the heap with space for one integer, set up its headers, etc. You could instead set one of the unused bits in the pointer to indicate that it's an integer and not a pointer, then store the integer in the remaining bits, avoiding the heap allocation at all. The Lisp world calls this a fixnum.
The more pointer bits you can steal, the more kinds of data you can store directly in the "pointer" itself. It's also possible to store the type of objects that are actually allocated on the heap in tags on the pointers to them, but I don't know if that's done any more.