Around 1990, Richard Stallman (RMS) and I were writing the GNU C library getopt() and he wanted to extend it to support long (multi-character) option names for user-friendliness. He considered Unix inferior in this regard to other operating systems such as TOPS-20 which supported long options (that could be abbreviated). He wanted GNU to be better than Unix while still compatible. There were a few programs that ran on Unix systems and used long option names starting with either - or no prefix at all, such as find, but those syntaxes were not compatible with Unix getopt() and were parsed by ad-hoc code.
Long options needed a prefix that wouldn’t clash with the Unix conventions, so programs could support both types of options without ambiguity. Richard chose +, since logically if - (for a small number mathematically) is for short options then + would be for long options, and it’s no additional typing. We created an extended interface called getopt_long() to support specifying long options.
But when the IEEE POSIX shell and utilities standard was published in 1992, the + syntax was disallowed. GNU developers discussed what to do over email. We considered -+ as the long options prefix, but that was hard to type, so we settled on --, which wouldn’t violate POSIX or Unix compatibility and wasn’t hard to type.
For a few months, GNU getopt() supported both + and -- to allow time for people to transition their scripts. I’m pretty sure support for + during that transition could be disabled by setting the environment variable POSIXMEHARDER (RMS’s exasperation with standards showing there), later changed to the more polite POSIXLY_CORRECT, which also disables recognizing options intermixed with positional arguments.
Because GNU software was popular and the solution was logical, everyone else adopted the -- prefix and implemented variations of it in their own argument parsers. Perl was probably one of the first.