diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4038104fbab53be732d1e3a94d955aca3f212dbb..d31398077c0959b0339e1f765d94f5d22011811c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -195,6 +195,7 @@ function(compile_flatbuffers_schema_to_cpp SRC_FBS)
     OUTPUT ${GEN_HEADER}
     COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}" -c --no-includes --gen-mutable
             --gen-object-api -o "${SRC_FBS_DIR}"
+            -I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
             "${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
     DEPENDS flatc)
 endfunction()
diff --git a/appveyor.yml b/appveyor.yml
index 0dd5a2ed1ebf980c1cf1e77100ece6dfc72e95a0..262d9b07ff7e750c52fb8611d00a8999224e63e5 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -35,7 +35,7 @@ test_script:
   - "JavaTest.bat"
   - rem "---------------- JS -----------------"
   - "node --version"
-  - "..\\%CONFIGURATION%\\flatc -b monster_test.fbs unicode_test.json"
+  - "..\\%CONFIGURATION%\\flatc -b -I include_test monster_test.fbs unicode_test.json"
   - "node JavaScriptTest ./monster_test_generated"
   - rem "---------------- C# -----------------"
   # Have to compile this here rather than in "build" above because AppVeyor only
diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h
index 262d2193770b754e795ccc1ad4f5f6d100149d21..2781852cdcd7d4a2247b142f5823eef571eaa435 100644
--- a/include/flatbuffers/idl.h
+++ b/include/flatbuffers/idl.h
@@ -590,7 +590,8 @@ private:
   FLATBUFFERS_CHECKED_ERROR SkipJsonString();
   FLATBUFFERS_CHECKED_ERROR DoParse(const char *_source,
                                     const char **include_paths,
-                                    const char *source_filename);
+                                    const char *source_filename,
+                                    const char *include_filename);
   FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef*> &fields,
                                        StructDef *struct_def,
                                        const char *suffix,
diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp
index 3789904483e65bc577cb700695e2ea349bb7e657..6bd958f5c7b0166a2d312e952ea82a443e5489c9 100644
--- a/src/idl_gen_cpp.cpp
+++ b/src/idl_gen_cpp.cpp
@@ -72,11 +72,11 @@ class CppGenerator : public BaseGenerator {
     }
     for (auto it = parser_.included_files_.begin();
          it != parser_.included_files_.end(); ++it) {
-      auto basename = flatbuffers::StripExtension(it->first);
-      if (!parser_.opts.keep_include_path)
-        basename = flatbuffers::StripPath(basename);
+      auto noext = flatbuffers::StripExtension(it->first);
+      auto basename = flatbuffers::StripPath(noext);
       if (basename != file_name_) {
-        code_ += "#include \"" + parser_.opts.include_prefix + basename +
+        code_ += "#include \"" + parser_.opts.include_prefix +
+                 (parser_.opts.keep_include_path ? noext : basename) +
                  "_generated.h\"";
         num_includes++;
       }
diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp
index 4c2556272200beb8d8bbcf05c37e0b06ab16c18c..f03ad9a88c27528bc6fb91fb9cea4b5ed955b347 100644
--- a/src/idl_parser.cpp
+++ b/src/idl_parser.cpp
@@ -1917,15 +1917,17 @@ CheckedError Parser::SkipJsonString() {
 
 bool Parser::Parse(const char *source, const char **include_paths,
                    const char *source_filename) {
-  return !DoParse(source, include_paths, source_filename).Check();
+  return !DoParse(source, include_paths, source_filename,
+                  source_filename).Check();
 }
 
 CheckedError Parser::DoParse(const char *source, const char **include_paths,
-                             const char *source_filename) {
+                             const char *source_filename,
+                             const char *include_filename) {
   file_being_parsed_ = source_filename ? source_filename : "";
   if (source_filename &&
-      included_files_.find(source_filename) == included_files_.end()) {
-    included_files_[source_filename] = true;
+      included_files_.find(include_filename) == included_files_.end()) {
+    included_files_[include_filename] = true;
     files_included_per_file_[source_filename] = std::set<std::string>();
   }
   if (!include_paths) {
@@ -1974,13 +1976,14 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths,
         return Error("unable to locate include file: " + name);
       if (source_filename)
         files_included_per_file_[source_filename].insert(filepath);
-      if (included_files_.find(filepath) == included_files_.end()) {
+      if (included_files_.find(name) == included_files_.end()) {
         // We found an include file that we have not parsed yet.
         // Load it and parse it.
         std::string contents;
         if (!LoadFile(filepath.c_str(), true, &contents))
           return Error("unable to load include file: " + name);
-        ECHECK(DoParse(contents.c_str(), include_paths, filepath.c_str()));
+        ECHECK(DoParse(contents.c_str(), include_paths, filepath.c_str(),
+                       name.c_str()));
         // We generally do not want to output code for any included files:
         if (!opts.generate_all) MarkGenerated();
         // This is the easiest way to continue this file after an include:
@@ -1990,7 +1993,7 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths,
         // entered into included_files_.
         // This is recursive, but only go as deep as the number of include
         // statements.
-        return DoParse(source, include_paths, source_filename);
+        return DoParse(source, include_paths, source_filename, include_filename);
       }
       EXPECT(';');
     } else {
diff --git a/tests/GoTest.sh b/tests/GoTest.sh
index 7be4affb77d86133aa2a79523aa1ce22dcb5d0c4..248a13f266b307ba2eeb747c847e92020be112b9 100755
--- a/tests/GoTest.sh
+++ b/tests/GoTest.sh
@@ -20,7 +20,7 @@ go_path=${test_dir}/go_gen
 go_src=${go_path}/src
 
 # Emit Go code for the example schema in the test dir:
-../flatc -g monster_test.fbs
+../flatc -g -I include_test monster_test.fbs
 
 # Go requires a particular layout of files in order to link multiple packages.
 # Copy flatbuffer Go files to their own package directories to compile the
diff --git a/tests/JavaScriptTest.sh b/tests/JavaScriptTest.sh
index cdba5fa69b1ce00da56c5fa8e00bd46201d66943..c0286a057005fdccd85c6caaaf5fcb3b93632ccb 100755
--- a/tests/JavaScriptTest.sh
+++ b/tests/JavaScriptTest.sh
@@ -15,5 +15,5 @@
 # limitations under the License.
 
 pushd "$(dirname $0)" >/dev/null
-../flatc -b monster_test.fbs unicode_test.json
+../flatc -b -I include_test monster_test.fbs unicode_test.json
 node JavaScriptTest ./monster_test_generated
diff --git a/tests/PythonTest.sh b/tests/PythonTest.sh
index 00fee7c7bb5692dd717a8998452a01d4f2e342e0..e4dbe8dae654c3bb9aa9abc1430dac470772a106 100755
--- a/tests/PythonTest.sh
+++ b/tests/PythonTest.sh
@@ -20,7 +20,7 @@ gen_code_path=${test_dir}
 runtime_library_dir=${test_dir}/../python
 
 # Emit Python code for the example schema in the test dir:
-${test_dir}/../flatc -p -o ${gen_code_path} monster_test.fbs
+${test_dir}/../flatc -p -o ${gen_code_path} -I include_test monster_test.fbs
 
 # Syntax: run_tests <interpreter> <benchmark vtable dedupes>
 #                   <benchmark read count> <benchmark build count>
diff --git a/tests/TypeScriptTest.sh b/tests/TypeScriptTest.sh
index 54c6d086c1e6933843a29b1956f9d941ffd3caca..b033a3024a318d0746df83e6381a1700b86f9986 100755
--- a/tests/TypeScriptTest.sh
+++ b/tests/TypeScriptTest.sh
@@ -15,8 +15,8 @@
 # limitations under the License.
 
 pushd "$(dirname $0)" >/dev/null
-../flatc --ts --no-fb-import --gen-mutable -o ts monster_test.fbs
-../flatc -b monster_test.fbs unicode_test.json
+../flatc --ts --no-fb-import --gen-mutable -o ts -I include_test monster_test.fbs
+../flatc -b -I include_test monster_test.fbs unicode_test.json
 npm install @types/flatbuffers
 tsc --strict --noUnusedParameters --noUnusedLocals --noImplicitReturns --strictNullChecks ts/monster_test_generated.ts
 npm uninstall @types/flatbuffers
diff --git a/tests/generate_code.bat b/tests/generate_code.bat
index e7660a2f2b30a7734318b5e603932fd919126f49..2abfe9b3c7459c2211d3ed27de6bef4e7b21805b 100644
--- a/tests/generate_code.bat
+++ b/tests/generate_code.bat
@@ -15,6 +15,6 @@
 set buildtype=Release
 if "%1"=="-b" set buildtype=%2
 
-..\%buildtype%\flatc.exe --cpp --java --csharp --go --binary --python --js --php --grpc --gen-mutable --gen-object-api --no-includes monster_test.fbs monsterdata_test.json
+..\%buildtype%\flatc.exe --cpp --java --csharp --go --binary --python --js --php --grpc --gen-mutable --gen-object-api --no-includes -I include_test monster_test.fbs monsterdata_test.json
 ..\%buildtype%\flatc.exe --cpp --java --csharp --go --binary --python --js --php --gen-mutable -o namespace_test namespace_test\namespace_test1.fbs namespace_test\namespace_test2.fbs
-..\%buildtype%\flatc.exe --binary --schema monster_test.fbs
+..\%buildtype%\flatc.exe --binary --schema -I include_test monster_test.fbs
diff --git a/tests/generate_code.sh b/tests/generate_code.sh
index bdce8405d498f442bb58caf635cf3326d64d58e5..8e3ac5112ce61df2cf33e2a18ddb49d900988e1c 100755
--- a/tests/generate_code.sh
+++ b/tests/generate_code.sh
@@ -14,11 +14,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-../flatc --cpp --java --csharp --go --binary --python --js --ts --php --grpc --gen-mutable --gen-object-api --no-includes --no-fb-import monster_test.fbs monsterdata_test.json
+../flatc --cpp --java --csharp --go --binary --python --js --ts --php --grpc --gen-mutable --gen-object-api --no-includes --no-fb-import -I include_test monster_test.fbs monsterdata_test.json
 ../flatc --cpp --java --csharp --go --binary --python --js --ts --php --gen-mutable --no-fb-import -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
 ../flatc --cpp --gen-mutable --gen-object-api -o union_vector ./union_vector/union_vector.fbs
-../flatc -b --schema --bfbs-comments monster_test.fbs
+../flatc -b --schema --bfbs-comments -I include_test monster_test.fbs
 cd ../samples
 ../flatc --cpp --gen-mutable --gen-object-api monster.fbs
 cd ../reflection
-sh generate_code.sh
diff --git a/tests/include_test/include_test1.fbs b/tests/include_test/include_test1.fbs
new file mode 100644
index 0000000000000000000000000000000000000000..39bc666beaf8329885491f768456a9de1c41df94
--- /dev/null
+++ b/tests/include_test/include_test1.fbs
@@ -0,0 +1,5 @@
+include "sub/include_test2.fbs";
+include "sub/include_test2.fbs";  // should be skipped
+include "include_test1.fbs";  // should be skipped
+
+
diff --git a/tests/include_test2.fbs b/tests/include_test/sub/include_test2.fbs
similarity index 61%
rename from tests/include_test2.fbs
rename to tests/include_test/sub/include_test2.fbs
index d22c0d9b4b9641d2ceebc9864a37ca390b00e04b..13aa229e88736b6c75a683d4a930001fe712ef59 100644
--- a/tests/include_test2.fbs
+++ b/tests/include_test/sub/include_test2.fbs
@@ -1,4 +1,4 @@
-include "include_test2.fbs";    // should be skipped
+include "sub/include_test2.fbs";    // should be skipped
 
 namespace MyGame.OtherNameSpace;
 
diff --git a/tests/include_test1.fbs b/tests/include_test1.fbs
deleted file mode 100644
index 11aebe81f375f776b031fbca32b28eb5c68d6ffa..0000000000000000000000000000000000000000
--- a/tests/include_test1.fbs
+++ /dev/null
@@ -1,5 +0,0 @@
-include "include_test2.fbs";
-include "include_test2.fbs";  // should be skipped
-include "include_test1.fbs";  // should be skipped
-
-
diff --git a/tests/test.cpp b/tests/test.cpp
index 3f5cddc4929caab0df496a5c7934e81626d1c3bf..3141a96858aaea773a3f8136343642ac3575b22a 100644
--- a/tests/test.cpp
+++ b/tests/test.cpp
@@ -472,7 +472,11 @@ void ParseAndGenerateTextTest() {
 
   // parse schema first, so we can use it to parse the data after
   flatbuffers::Parser parser;
-  const char *include_directories[] = { test_data_path.c_str(), nullptr };
+  auto include_test_path =
+      flatbuffers::ConCatPathFileName(test_data_path, "include_test");
+  const char *include_directories[] = {
+    test_data_path.c_str(), include_test_path.c_str(), nullptr
+  };
   TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
   TEST_EQ(parser.Parse(jsonfile.c_str(), include_directories), true);