diff --git a/SystemTools.cxx b/SystemTools.cxx
index 3f5d0e34d01c9730caa5d1c1aea1a1202411faa2..f257b976d4a252c839cb4c5e0cce2dc047a9f91f 100644
--- a/SystemTools.cxx
+++ b/SystemTools.cxx
@@ -2071,6 +2071,29 @@ bool SystemTools::IsSubDirectory(const char* cSubdir, const char* cDir)
   return false;
 }
 
+kwsys_stl::string SystemTools::FileExistsInParentDirectories(const char* fname,
+  const char* directory, const char* toplevel)
+{
+  kwsys_stl::string file = fname;
+  SystemTools::ConvertToUnixSlashes(file);
+  kwsys_stl::string dir = directory;
+  SystemTools::ConvertToUnixSlashes(dir);
+  while ( 1 )
+    {
+    kwsys_stl::string path = dir + "/" + file;
+    if ( SystemTools::FileExists(path.c_str()) )
+      {
+      return path;
+      }
+    if ( dir.size() < strlen(toplevel) )
+      {
+      break;
+      }
+    dir = SystemTools::GetParentDirectory(dir.c_str());
+    }
+  return "";
+}
+
 // These must NOT be initialized.  Default initialization to zero is
 // necessary.
 unsigned int SystemToolsManagerCount;
diff --git a/SystemTools.hxx.in b/SystemTools.hxx.in
index f80c93704ffd07925fde1d16b13e27b4e5ea4082..2b73b7c653f96900202900fefd1753e910838f15 100644
--- a/SystemTools.hxx.in
+++ b/SystemTools.hxx.in
@@ -322,6 +322,12 @@ public:
   /** Check if the given file or directory is in subdirectory of dir */
   static bool IsSubDirectory(const char* fileOrDir, const char* dir);
 
+  /** Check if the given file exists in one of the parent directory of the
+   * given file or directory and if it does, return the name of the file.
+   * Toplevel specifies the top-most directory to where it will look.*/
+  static kwsys_stl::string FileExistsInParentDirectories(const char* fname,
+    const char* directory, const char* toplevel);
+
 protected:
   // these two functions can be called from ConvertToOutputPath
   /**