diff --git a/compiler/fpcp.pas b/compiler/fpcp.pas
index 59dcfb99e5..424736cf85 100644
--- a/compiler/fpcp.pas
+++ b/compiler/fpcp.pas
@@ -57,6 +57,7 @@ interface
       function getmodulestream(module:tmodulebase):tcstream;
       procedure initmoduleinfo(module:tmodulebase);
       procedure addunit(module:tmodulebase);
+      procedure add_required_package(pkg:tpackage);
     end;
 
 implementation
@@ -551,5 +552,19 @@ implementation
       containedmodules.add(module.modulename^,containedunit);
     end;
 
+
+  procedure tpcppackage.add_required_package(pkg:tpackage);
+    var
+      p : tpackage;
+    begin
+      p:=tpackage(requiredpackages.find(pkg.packagename^));
+      if not assigned(p) then
+        requiredpackages.Add(pkg.packagename^,pkg)
+      else
+        if p<>pkg then
+          internalerror(2015112302);
+    end;
+
+
 end.
 
diff --git a/compiler/fpkg.pas b/compiler/fpkg.pas
index 8638faeff6..44219dc416 100644
--- a/compiler/fpkg.pas
+++ b/compiler/fpkg.pas
@@ -56,6 +56,7 @@ interface
       package : tpackage;
       realpkgname : string;
       usedunits : longint;
+      direct : boolean;
     end;
     ppackageentry=^tpackageentry;
 
diff --git a/compiler/options.pas b/compiler/options.pas
index 052bb3a19a..8752f6ff9e 100644
--- a/compiler/options.pas
+++ b/compiler/options.pas
@@ -1555,7 +1555,7 @@ begin
                      if ispara then
                        parapackages.add(more,nil)
                      else
-                       add_package(more,true);
+                       add_package(more,true,true);
                    end;
                  'p' :
                    begin
@@ -3637,7 +3637,7 @@ begin
   FrameworkSearchPath.AddList(option.ParaFrameworkPath,true);
   packagesearchpath.addlist(option.parapackagepath,true);
   for j:=0 to option.parapackages.count-1 do
-    add_package(option.parapackages.NameOfIndex(j),true);
+    add_package(option.parapackages.NameOfIndex(j),true,true);
 
   { add unit environment and exepath to the unit search path }
   if inputfilepath<>'' then
diff --git a/compiler/pkgutil.pas b/compiler/pkgutil.pas
index d5d2492e07..670a2a44cf 100644
--- a/compiler/pkgutil.pas
+++ b/compiler/pkgutil.pas
@@ -33,7 +33,7 @@ interface
   Function RewritePPU(const PPUFn:String;OutStream:TCStream):Boolean;
   procedure export_unit(u:tmodule);
   procedure load_packages;
-  procedure add_package(const name:string;ignoreduplicates:boolean);
+  procedure add_package(const name:string;ignoreduplicates:boolean;direct:boolean);
   procedure add_package_unit_ref(package:tpackage);
   procedure add_package_libs(l:tlinker);
 
@@ -382,13 +382,17 @@ implementation
 
   procedure load_packages;
     var
-      i : longint;
+      i,j : longint;
       pcp: tpcppackage;
-      entry : ppackageentry;
+      entry,
+      entryreq : ppackageentry;
+      name,
+      uname : string;
     begin
       if not (tf_supports_packages in target_info.flags) then
         exit;
-      for i:=0 to packagelist.count-1 do
+      i:=0;
+      while i<packagelist.count do
         begin
           entry:=ppackageentry(packagelist[i]);
           if assigned(entry^.package) then
@@ -397,11 +401,46 @@ implementation
           pcp:=tpcppackage.create(entry^.realpkgname);
           pcp.loadpcp;
           entry^.package:=pcp;
+
+          { add all required packages that are not yet part of packagelist }
+          for j:=0 to pcp.requiredpackages.count-1 do
+            begin
+              name:=pcp.requiredpackages.NameOfIndex(j);
+              uname:=upper(name);
+              if not assigned(packagelist.Find(uname)) then
+                begin
+                  New(entryreq);
+                  entryreq^.realpkgname:=name;
+                  entryreq^.package:=nil;
+                  entryreq^.usedunits:=0;
+                  entryreq^.direct:=false;
+                  packagelist.add(uname,entryreq);
+                end;
+            end;
+
+          Inc(i);
+        end;
+
+      { all packages are now loaded, so we can fill in the links of the required packages }
+      for i:=0 to packagelist.count-1 do
+        begin
+          entry:=ppackageentry(packagelist[i]);
+          if not assigned(entry^.package) then
+            internalerror(2015111301);
+          for j:=0 to entry^.package.requiredpackages.count-1 do
+            begin
+              if assigned(entry^.package.requiredpackages[j]) then
+                internalerror(2015111303);
+              entryreq:=packagelist.find(upper(entry^.package.requiredpackages.NameOfIndex(j)));
+              if not assigned(entryreq) then
+                internalerror(2015111302);
+              entry^.package.requiredpackages[j]:=entryreq^.package;
+            end;
         end;
     end;
 
 
-  procedure add_package(const name:string;ignoreduplicates:boolean);
+  procedure add_package(const name:string;ignoreduplicates:boolean;direct:boolean);
     var
       entry : ppackageentry;
       i : longint;
@@ -419,6 +458,7 @@ implementation
       entry^.package:=nil;
       entry^.realpkgname:=name;
       entry^.usedunits:=0;
+      entry^.direct:=direct;
       packagelist.add(upper(name),entry);
     end;
 
diff --git a/compiler/pmodules.pas b/compiler/pmodules.pas
index 2b6b8fab2b..c68d7a30d5 100644
--- a/compiler/pmodules.pas
+++ b/compiler/pmodules.pas
@@ -1384,6 +1384,7 @@ type
         force_init_final : boolean;
         uu : tused_unit;
         module_name: ansistring;
+        pentry: ppackageentry;
       begin
          Status.IsPackage:=true;
          Status.IsExe:=true;
@@ -1482,7 +1483,7 @@ type
                          module_name:=module_name+'.'+orgpattern;
                          consume(_ID);
                        end;
-                     add_package(module_name,false);
+                     add_package(module_name,false,true);
                    end
                  else
                    consume(_ID);
@@ -1721,8 +1722,18 @@ type
              hp:=tmodule(loaded_units.first);
              while assigned(hp) do
               begin
-                if (hp<>current_module) and not assigned(hp.package) then
-                  pkg.addunit(hp);
+                if (hp<>current_module) then
+                  begin
+                    if not assigned(hp.package) then
+                      pkg.addunit(hp)
+                    else
+                      begin
+                        pentry:=ppackageentry(packagelist.find(hp.package.packagename^));
+                        if not assigned(pentry) then
+                          internalerror(2015112301);
+                        pkg.add_required_package(hp.package);
+                      end;
+                  end;
                 hp:=tmodule(hp.next);
               end;