Homoiconicity means you're code is defined in terms of the same data structures that are used in programs written in the language. This makes self-modifying code and metaprogramming easier because the language's standard library is already full of functions that operate on those data structures.
However, you can have self-modifying code and metaprogramming without homoiconicity, and you can have homoiconicity without support for self-modifying code and metaprogramming.
However, you can have self-modifying code and metaprogramming without homoiconicity, and you can have homoiconicity without support for self-modifying code and metaprogramming.