The way I like to see it is as a tool to transfer promises through unknown code.
unknown user code
Λ \
/ V
library 1 library 2
Both libraries have unsafe code, but can only communicate through unknown user code that might do arbitrary weird things. How can library 1 promise library 2 that an object will never again move? The unknown user code probably doesn't have an unsafe block, so the unsafe code in the two libraries must be correct regardless of what crazy things the user code does.
The Pin type allows you to transfer such a promise by having library 1 give a pinned pointer the user code, which then passes it on to library 2. Since a pinned pointer to a non-Unpin type is opaque without the use of unsafe code, the user code can't do anything to the value behind it.
Some example of libraries: Library 1 might be the implementation of Box::pin, tokio::pin!, or the inners of tokio::spawn. The most common example of library 2 is the auto-generated code inside an async function, but also includes custom streams (example) or futures.