diff --git a/src/lua/init.c b/src/lua/init.c
index 1fb0d3d2a12e70ca51406779a03ff24a4ef89ca1..30bcf828d900e49a11e15f1d48cf84b9c4b03b11 100644
--- a/src/lua/init.c
+++ b/src/lua/init.c
@@ -913,6 +913,10 @@ tarantool_lua_init(const char *tarantool_bin, const char *script, int argc,
 	}
 	lua_setfield(L, LUA_GLOBALSINDEX, "arg");
 
+	/* Create a table for "package.searchers" analogue. */
+	lua_newtable(L);
+	lua_setfield(L, LUA_REGISTRYINDEX, "_TARANTOOL_PACKAGE_SEARCHERS");
+
 	/*
 	 * Create a table for storing loaded built-in modules.
 	 * Similar to _LOADED (package.loaded).
diff --git a/src/lua/loaders.lua b/src/lua/loaders.lua
index 6fe08eda0b4b12c0c573da37ac40b1c49e9d1d3c..d21be37a42be2dd394d068d71a3ffca073ad3f5b 100644
--- a/src/lua/loaders.lua
+++ b/src/lua/loaders.lua
@@ -14,34 +14,6 @@ local ROCKS_LUA_TEMPLATES = {
     ROCKS_LUA_PATH .. '/?/init.lua',
 }
 
--- Tarantool's builtin modules.
---
--- Similar to _LOADED (package.loaded).
-local builtin_modules = debug.getregistry()._TARANTOOL_BUILTIN
-
--- Loader for built-in modules.
-local function builtin_loader(name)
-    -- A loader is more like a searching function rather than a
-    -- loading function (fun fact: package.loaders was renamed to
-    -- package.searchers in Lua 5.2).
-    --
-    -- A loader (a searcher) typically searches for a file and, if
-    -- the file is found, loads it and returns a function to
-    -- execute it. Typically just result of loadfile(file).
-    --
-    -- Our 'filesystem' is a table of modules, a 'file' is an
-    -- entry in the table. If a module is found, the loader
-    -- returns a function that 'executes' it. The function just
-    -- returns the module itself.
-    if builtin_modules[name] ~= nil then
-        return function(_name)
-            return builtin_modules[name]
-        end
-    end
-
-    return ("\n\tno field loaders.builtin['%s']"):format(name)
-end
-
 local package_searchroot
 
 local function searchroot()
@@ -119,6 +91,33 @@ local function gen_search_func(path_fn, templates, need_traverse)
     end
 end
 
+-- Lua table with "package searchers".
+local searchers = debug.getregistry()._TARANTOOL_PACKAGE_SEARCHERS
+
+rawset(searchers, 'preload', function(name)
+    assert(type(package.preload) == 'table',
+           "'package.preload' must be a table")
+    local loader = package.preload[name]
+    if loader ~= nil then
+        return loader, ':preload:'
+    end
+    return ("\n\tno field package.preload['%s']"):format(name)
+end)
+
+-- Tarantool's builtin modules.
+--
+-- Similar to _LOADED (package.loaded).
+local builtin_modules = debug.getregistry()._TARANTOOL_BUILTIN
+
+-- Searcher for builtin modules.
+rawset(searchers, 'builtin', function(name)
+    local module = builtin_modules[name]
+    if module ~= nil then
+        return function(_name) return module end, ':builtin:'
+    end
+    return ("\n\tno field loaders.builtin['%s']"):format(name)
+end)
+
 -- Compose a loader function from options.
 --
 -- @param search_fn function will be used to search a file from
@@ -351,6 +350,23 @@ local override_loader = conditional_loader(chain_loaders({
     prefix_loader('override', package.loaders[7]),
 }), override_loader_onoff)
 
+
+local function dummy_loader(searcher, sentinel)
+    return function(name)
+        local loader, data = searcher(name)
+        -- XXX: <loader> (i.e. the first return value) contains
+        -- error message in this case. Just propagate it to the
+        -- <require> frame...
+        if not data then
+           return loader
+        end
+        -- XXX: ... Otherwise, this is a valid module loader.
+        -- Check the <data> and return the <loader> function.
+        assert(data == sentinel, 'Invalid searcher')
+        return loader
+    end
+end
+
 -- Add two loaders:
 --
 -- - Search for override.<module_name> module. It is necessary for
@@ -362,9 +378,9 @@ local override_loader = conditional_loader(chain_loaders({
 -- change ordinals of the loaders 2-8. It is possible that someone
 -- has a logic based on those loader positions.
 package.loaders[1] = chain_loaders({
-    package.loaders[1],
+    dummy_loader(searchers['preload'], ':preload:'),
     override_loader,
-    builtin_loader,
+    dummy_loader(searchers['builtin'], ':builtin:'),
 })
 
 rawset(package, "search", search)