How to implement custom icons for my script/addon? Is it possible to use different icons other than the default set and how?
Since 2.75 the python API allows for custom icons.
You can store custom icons and load them with bpy.utils.previews.ImagePreviewCollection class, which works like a dictionary.
First let's create such icon dictionary:
import bpy.utils.previews
icons_dict = bpy.utils.previews.new()

Next, we need to find path to our icons. Its best to put them inside a folder named 'icons' next to the script file:
import os
# this will work for addons 
icons_dir = os.path.join(os.path.dirname(__file__), &quot;icons&quot;)
# but it won't give you usefull path when you opened a file in text editor and hit run.
# this will work in that case:
script_path = bpy.context.space_data.text.filepath
icons_dir = os.path.join(os.path.dirname(script_path), &quot;icons&quot;)

Finally load icon.png into the dictionary. Blender uses 32x32 icons in UI:
icons_dict.load(&quot;custom_icon&quot;, os.path.join(icons_dir, &quot;icon.png&quot;), 'IMAGE')

Reference the icon by it's ID, use like this inside UI elements:
icon_value=icons_dict[&quot;custom_icon&quot;].icon_id


It's best to handle loading of icons in the register function, clearing the icons in unregister function, and storing them in a global variable.
If enabled as an addon the filepath of __init__.py is the module variable __file__ in __init__.py and as shown can be converted to a directory path using os.path.dirname(__file__) to get the path to my_addon
Make an add-on with multiple python files to keep our addon's icons neatly contained in our addon's folder.
my_addon/
    __init__.py
    icons/
        icon.png

To test when running from text editor can  add an icons folder to some known path, for example the Desktop folder
Desktop/
    icons/
        icon.png 

and change the code below accordingly to be its absolute path (in this example case /home/user/Desktop/), or  the saved path of the text file, or that of the blend file.
bl_info = {
    &quot;name&quot;: &quot;Custom Icon Test&quot;,
    &quot;author&quot;: &quot;Your Name Here&quot;,
    &quot;version&quot;: (1, 0),
    &quot;blender&quot;: (2, 80, 0),
    &quot;location&quot;: &quot;View3D &gt; UI &gt; Tools&quot;,
    &quot;description&quot;: &quot;Test custom icons&quot;,
    &quot;warning&quot;: &quot;&quot;,
    &quot;doc_url&quot;: &quot;&quot;,
    &quot;category&quot;: &quot;Testing&quot;,
}

import os
import bpy
import bpy.utils.previews

class CUSTOM_PT_myPanel(bpy.types.Panel):
    bl_label = &quot;My Icon Panel&quot;
    bl_idname = &quot;OBJECT_PT_custom_panel&quot;
    bl_space_type = &quot;VIEW_3D&quot;   
    bl_region_type = &quot;UI&quot;
    bl_category = &quot;Tools&quot;

    def draw(self, context):
        global custom_icons
        self.layout.label(text=&quot;Blender SE&quot;, icon_value=custom_icons[&quot;custom_icon&quot;].icon_id)

# global variable to store icons in
custom_icons = None

def register():
    global custom_icons
    custom_icons = bpy.utils.previews.new()
    addon_path =  os.path.dirname(__file__)
    icons_dir = os.path.join(addon_path, &quot;icons&quot;)
    
    custom_icons.load(&quot;custom_icon&quot;, os.path.join(icons_dir, &quot;icon.png&quot;), 'IMAGE')
    bpy.utils.register_class(CUSTOM_PT_myPanel)

def unregister():
    global custom_icons
    bpy.utils.previews.remove(custom_icons)
    bpy.utils.unregister_class(CUSTOM_PT_myPanel)

if __name__ == &quot;__main__&quot;:
    # Test run
    # edit to folder containing your icons folder
    __file__ = &quot;/home/user/Desktop/&quot;
    # The path of this text (if saved)
    #__file__ = bpy.context.space_data.text.filepath
    # The path of this blend file (if saved)
    #__file__ = bpy.data.filepath
    register()

Result: