The main difference is mentioned in (elisp) `Plists and Alists':
In contrast to association lists, the order of the pairs
in the property list is not significant since the property
names must be distinct.
That gives alists the ability to shadow associations.
An association list may be used like a stack where associations
are pushed on the front of the list and later discarded...
And it means that:
All properties for a symbol are stored in the same property
list, so there is a possibility of a conflict between different
uses of a property name.
[But sure, you could use a plist as a stack, with shadowing, by defining your
own accessor etc. It's just a list, after all. But `plist-get' and `get' do
not act that way.]
The advantage for plists pointed out in that doc section is that plists are what
you get with symbols - they are built in. It contrasts a global alist with the
plists associated with individual symbols.
[But that's just the way things are designed. Lisp could be/have been designed
with individual symbols having asssociated alists instead of plists.]
Here is another typical difference (from (elisp) `Association Lists'):
Both the values and the keys in an alist may be any Lisp
objects. For example, in the following alist, the symbol
`a' is associated with the number `1', and the string `"b"'
is associated with the _list_ `(2 3)', which is the CDR of
the alist element: ((a . 1) ("b" 2 3))
[But again, a plist too could use anything as a key, provided you roll your own
accessor. But `plist-get' and `get' use `eq' comparison.]
In short, each is just a list; each is general enough to replace the other. But
to do so means going beyond the usual accessors etc. And in the case of symbol
properties it would require a different Lisp implementation (or some indirection