diff --git a/python/dumux/common/properties.py b/python/dumux/common/properties.py
index a456c4de6a51d5ba5adb3df55099bb54513b58cb..c42054908b276997d73af1ca3d034a10263be8a3 100644
--- a/python/dumux/common/properties.py
+++ b/python/dumux/common/properties.py
@@ -195,6 +195,31 @@ def predefinedProperties():
         return properties
 
 
+def predefinedTypeTags(inheritsFrom=None):
+    """Create a list of predefined TypeTags"""
+    result = _typeTags
+    if inheritsFrom is not None:
+        for parentTypeTag in inheritsFrom:
+            if isinstance(parentTypeTag, CppTypeTag):
+                result[parentTypeTag.name] = {
+                    "include": parentTypeTag.includes[0],
+                    "description": parentTypeTag.description,
+                }
+    return result
+
+
+class CppTypeTag:
+    """Creates a TypeTag from an existing c++ TypeTag"""
+
+    def __init__(self, *, name, include, description=None):
+        self.name = name
+        self.includes = [include]
+        self.description = description
+        self.isExistingTypeTag = True
+        self.properties = {}
+        self.newPropertyDefinitions = []
+
+
 class TypeTag:
     """TypeTags are inheritable collections of properties"""
 
@@ -208,32 +233,34 @@ class TypeTag:
         self.gridGeometry = gridGeometry
         self.name = name
 
-        if self.name in _typeTags:
+        existingTypeTags = predefinedTypeTags(self.inheritsFrom)
+
+        if self.name in existingTypeTags:
             if inheritsFrom is not None:
                 raise ValueError(
                     f"Existing TypeTag {name} cannot inherit from other TypeTags."
                     f" Use TypeTag({name}) only."
                 )
             self.isExistingTypeTag = True
-            self.includes = [_typeTags[self.name]["include"]]
+            self.includes = [existingTypeTags[self.name]["include"]]
         else:
             self.isExistingTypeTag = False
 
         if self.inheritsFrom is not None:
             # treat existing TypeTags by converting the given string to a real TypeTag instance
             for idx, parentTypeTag in enumerate(self.inheritsFrom):
-                if not isinstance(parentTypeTag, TypeTag):
+                if not isinstance(parentTypeTag, (CppTypeTag, TypeTag)):
                     if not isinstance(parentTypeTag, str):
                         raise ValueError(
                             f"Unknown parent TypeTag {parentTypeTag}. "
                             "Use either argument of type TypeTag "
                             "or a string for an existing TypeTag. "
-                            f"List of existing TypeTags: {_typeTags.keys()}"
+                            f"List of existing TypeTags: {existingTypeTags.keys()}"
                         )
-                    if parentTypeTag not in _typeTags.keys():
+                    if parentTypeTag not in existingTypeTags.keys():
                         raise ValueError(
                             f"Unknown TypeTag {parentTypeTag}. "
-                            f"List of existing TypeTags: {_typeTags.keys()}"
+                            f"List of existing TypeTags: {existingTypeTags.keys()}"
                         )
                     self.inheritsFrom[idx] = TypeTag(parentTypeTag)
 
@@ -327,9 +354,24 @@ class TypeTag:
 class Model(TypeTag):
     """A DuMux model specifies all properties necessary to build a DuMux simulator"""
 
-    def __init__(self, *, inheritsFrom: List[str], gridGeometry, scalar: str = "double"):
+    def __init__(self, *, inheritsFrom, gridGeometry, scalar: str = "double"):
+
+        inheritsFromNames = []
+        for parentModel in inheritsFrom:
+            if isinstance(parentModel, str):
+                inheritsFromNames.append(parentModel)
+            elif isinstance(parentModel, (CppTypeTag, TypeTag)):
+                inheritsFromNames.append(parentModel.name)
+            else:
+                raise ValueError(
+                    "Arguments passed to inheritsFrom must be either names (strings) of "
+                    "known TypeTags, TypeTag objects or CppTypeTag objects."
+                )
+
         # generate a generic name
-        genericName = "TypeTag" + hashIt("".join(inheritsFrom) + gridGeometry._typeName + scalar)
+        genericName = "TypeTag" + hashIt(
+            "".join(inheritsFromNames) + gridGeometry._typeName + scalar
+        )
 
         # deduce the discretization tag from the grid geometry
         discretizationMethod = gridGeometry.discMethod