diff --git a/include/VirtualModule.h b/include/VirtualModule.h
index a2ca1bfe6b3f4de305d17efe3b91b539870e2151..ae8e873e1a5762b66f666073188fd9eaaa9513c7 100644
--- a/include/VirtualModule.h
+++ b/include/VirtualModule.h
@@ -44,6 +44,13 @@ namespace ChimeraTK {
       /** Add a virtual sub-module. The module instance will be added to an internal list. */
       void addSubModule(VirtualModule module);
 
+      /** Return the submodule with the given name. If it doesn't exist, create it first. */
+      VirtualModule& createAndGetSubmodule(const std::string& moduleName);
+
+      /** Like createAndGetSubmodule(), but recursively create a hierarchy of submodules separated by "/" in the
+       *  moduleName. */
+      VirtualModule& createAndGetSubmoduleRecursive(const std::string& moduleName);
+
       ModuleType getModuleType() const override { return _moduleType; }
 
       const Module& virtualise() const override;
diff --git a/src/DeviceModule.cc b/src/DeviceModule.cc
index 05a67cfb632f012fba300be956db0b47d1b2e92d..6d8fb8ee37f923ca2a635a8036a48593c58282a7 100644
--- a/src/DeviceModule.cc
+++ b/src/DeviceModule.cc
@@ -131,9 +131,12 @@ namespace ChimeraTK {
       }
 
       auto name = std::string(reg.getRegisterName()).substr(prefixLength);
-      VariableNetworkNode node(name, deviceAliasOrURI, reg.getRegisterName(), updateMode,
+      auto lastSlash = name.find_last_of("/");
+      auto dirname = name.substr(0,lastSlash);
+      auto basename = name.substr(lastSlash+1);
+      VariableNetworkNode node(basename, deviceAliasOrURI, reg.getRegisterName(), updateMode,
                                direction, *valTyp, reg.getNumberOfElements());
-      virtualisedModuleFromCatalog.getAccessorList().push_back(node);
+      virtualisedModuleFromCatalog.createAndGetSubmoduleRecursive(dirname).getAccessorList().push_back(node);
 
     }
 
diff --git a/src/VirtualModule.cc b/src/VirtualModule.cc
index 805d8af3e4a6ebb02780aa1d68ab27c6e38b13a3..f631466380325c9003039ac00e4204dd2919942b 100644
--- a/src/VirtualModule.cc
+++ b/src/VirtualModule.cc
@@ -107,5 +107,34 @@ namespace ChimeraTK {
     return *this;
   }
 
+/*********************************************************************************************************************/
+
+  VirtualModule& VirtualModule::createAndGetSubmodule(const std::string& moduleName) {
+    for(auto &sm : submodules) {
+      if(sm.getName() == moduleName) return sm;
+    }
+    addSubModule(VirtualModule(moduleName, getDescription(), getModuleType()));
+    return submodules.back();
+  }
+
+/*********************************************************************************************************************/
+
+  VirtualModule& VirtualModule::createAndGetSubmoduleRecursive(const std::string& moduleName) {
+    auto slash = moduleName.find_first_of("/");
+    if(slash == std::string::npos) {
+      return createAndGetSubmodule(moduleName);
+    }
+    else {
+      auto firstSubmodule = moduleName.substr(0,slash);
+      auto remainingSubmodules = moduleName.substr(slash+1);
+      auto &sm = createAndGetSubmodule(firstSubmodule);
+      sm.createAndGetSubmoduleRecursive(remainingSubmodules);
+      return sm;
+    }
+  }
+
+/*********************************************************************************************************************/
+
+
 } /* namespace ChimeraTK */