diff --git a/README b/README
index ae011f3..232da2b 100644
--- a/README
+++ b/README
@@ -46,6 +46,10 @@ to be tailored for your environment.
 * Enable the refpolicy-mls:
 e.g. PREFERRED_PROVIDER_virtual/refpolicy ?= "refpolicy-mls"
 
+In order to activate the labeling mechanism for packages you have to add
+'selinux-package-labeling' to the INHERIT variable in your local.conf.
+e.g. INHERIT += "selinux-package-labeling"
+
 
 Using different init manager
 ----------------------------
diff --git a/classes/selinux-package-labeling.bbclass b/classes/selinux-package-labeling.bbclass
new file mode 100644
index 0000000..0edc284
--- /dev/null
+++ b/classes/selinux-package-labeling.bbclass
@@ -0,0 +1,76 @@
+def get_installed_folders_and_files(folder):
+    folders_and_files = []
+    if folder[-1] == "/":
+        # remove trailing slash, so it won't be removed later
+        folder = folder[:-1]
+    for walkroot, _, _files in os.walk(folder):
+        if walkroot == folder:
+            # The root folder should never be labeled when installing a package
+            continue
+        folders_and_files.append(walkroot.replace(folder, ""))
+        for file in _files:
+            folders_and_files.append(os.path.join(walkroot, file).replace(folder, ""))
+
+    return folders_and_files
+
+
+def get_installed_items(d, pkg):
+    pkgdest = d.getVar('PKGDEST')
+    pkg_folder = os.path.join(pkgdest, pkg)
+    retval = get_installed_folders_and_files(pkg_folder)
+
+    return retval
+
+
+python do_add_labels_in_postinst() {
+    packages = d.getVar('PACKAGES')
+    for pkg in packages.split():
+        # get the files inside the package
+        items = get_installed_items(d, pkg)
+
+        if not items:
+            continue
+
+        postinst = d.getVar('pkg_postinst:%s' % pkg)
+
+        # Circular dependencies in postscript happen, if two recipes depends on
+        # each other and both have a postinst script. As we label the newly installed files
+        # in the postinst script, we can ignore these circular dependencies if only one
+        # of the pkg have a postinst script. The check takes place in
+        # rootfs.py:_get_delayed_postinsts_common
+        if d.getVar("IGNORE_POSTINST_CIRCULAR_DEPENDENCY_{}".format(pkg)) and postinst:
+             bb.fatal("Circular dependency shall be ignored, but postinst script is given")
+
+        # Create the postinst script, which uses restorecon (busybox-util) for labeling
+        # add an empty line so that we don't append on a existing line.
+        relabel_command = d.getVar("PKG_RESTORECON")
+        postinst_labeling_command = "\t\t\techo -e \"{}\" | " \
+            "{}\n".format("\n".join(sorted(items)), relabel_command)
+
+        if not postinst:
+            postinst = '#!/bin/sh'
+        postinst += "\nif [ x\"$D\" = \"x\" ]; then\n"
+        postinst += "\tif command -v selinuxenabled > /dev/null 2>&1; then\n"
+        postinst += "\t\tif selinuxenabled; then\n"
+        postinst += postinst_labeling_command
+        postinst += "\t\tfi\n"
+        postinst += "\tfi\n"
+        postinst += "fi\n"
+
+        d.setVar('pkg_postinst:' + pkg, postinst)
+}
+
+# The restorecon binary gets the paths via stdin
+PKG_RESTORECON ?= "/sbin/restorecon -i -f -"
+
+python () {
+    if not bb.utils.contains('DISTRO_FEATURES', 'selinux', True, False, d):
+        # Only add the postinst label command if selinux is enabled
+        return
+
+    if bb.data.inherits_class('packagegroup', d):
+        return
+
+    if "class-target" in d.getVar("OVERRIDES").split(":"):
+        d.appendVar("PACKAGE_POSTPROCESS_FUNCS", "do_add_labels_in_postinst")
+}
