diff --git a/CMakeLists.txt b/CMakeLists.txt
index 79bc85cf8f3aa8440ca0a63cd791348b27f8b052..fb4ce8c0fddc9c59d62a584d01780830020339f3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -78,6 +78,8 @@ option ( WALBERLA_BUILD_WITH_OPENMP         "Enable OpenMP support"
 option ( WALBERLA_BUILD_WITH_PYTHON         "Support for embedding Python"                       )
 option ( WALBERLA_BUILD_WITH_PYTHON_MODULE  "Build waLBerla python module"                       )
 option ( WALBERLA_BUILD_WITH_PYTHON_LBM     "Include LBM module into python module"          OFF )
+option ( WALBERLA_BUILD_WITH_CODEGEN        "Enable pystencils code generation"              OFF )
+
 
 option ( WALBERLA_BUILD_WITH_LIKWID_MARKERS "Compile in markers for likwid-perfctr"              )
 
@@ -494,6 +496,24 @@ endif ( )
 
 
 
+############################################################################################################################
+##
+## Code Generation (pystencils)
+##
+#############################################################################################################################
+if ( WALBERLA_BUILD_WITH_CODEGEN )
+    find_package( PythonInterp 3 QUIET REQUIRED)
+    execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import pystencils_walberla" RESULT_VARIABLE PYTHON_RET_CODE)
+    if(NOT PYTHON_RET_CODE EQUAL 0)
+        message(FATAL_ERROR "WALBERLA_BUILD_WITH_CODEGEN activated and pystencils_walberla package not found")
+    endif()
+
+endif()
+############################################################################################################################
+
+
+
+
 ############################################################################################################################
 ##
 ## Python Libraries
diff --git a/cmake/waLBerlaFunctions.cmake b/cmake/waLBerlaFunctions.cmake
index cf594b58fda76ea7303b07cadab6fffc00eac5a9..0913ac63f851299d5e9f21b8e2dfc2d95bfaf818 100644
--- a/cmake/waLBerlaFunctions.cmake
+++ b/cmake/waLBerlaFunctions.cmake
@@ -89,16 +89,22 @@ function ( waLBerla_add_module )
  	   endif( ) 
  	endforeach( ) 
 
- 	if ( hasSourceFiles )
- 	    if ( CUDA_FOUND )
+    if ( hasSourceFiles )
+
+        handle_python_codegen(sourceFiles codeGenRequired ${sourceFiles})
+        if( NOT WALBERLA_BUILD_WITH_CODEGEN AND codeGenRequired)
+            message(STATUS "Skipping ${ARG_NAME} since pystencils code generation is not enabled")
+            return()
+        endif()
+
+        if ( CUDA_FOUND )
             cuda_add_library( ${moduleLibraryName} STATIC ${sourceFiles} ${otherFiles} )
         else()
             add_library( ${moduleLibraryName} STATIC ${sourceFiles} ${otherFiles} )
         endif( CUDA_FOUND )
  	else( ) 
  	   add_custom_target( ${moduleLibraryName} SOURCES ${sourceFiles} ${otherFiles} )  # dummy IDE target 
- 	endif( ) 
-
+ 	endif( )
     waLBerla_register_dependency ( ${moduleName} ${ARG_DEPENDS} )
 
     # This property is needed for visual studio to group modules together
@@ -198,14 +204,19 @@ function ( waLBerla_add_executable )
         endif ( )
     endif()
 
+    handle_python_codegen(sourceFiles codeGenRequired ${sourceFiles})
+    if( NOT WALBERLA_BUILD_WITH_CODEGEN AND codeGenRequired)
+        message(STATUS "Skipping ${ARG_NAME} since pystencils code generation is not enabled")
+        return()
+    endif()
+
     if ( CUDA_FOUND )
         cuda_add_executable( ${ARG_NAME} ${sourceFiles} )
     else()
         add_executable( ${ARG_NAME} ${sourceFiles} )
     endif()
 
-    #add_executable( ${ARG_NAME} ${sourceFiles} )
-    target_link_modules  ( ${ARG_NAME} ${ARG_DEPENDS}  )    
+    target_link_modules  ( ${ARG_NAME} ${ARG_DEPENDS}  )
     target_link_libraries( ${ARG_NAME} ${SERVICE_LIBS} )
 
     if( WALBERLA_GROUP_PROJECTS )
diff --git a/cmake/waLBerlaHelperFunctions.cmake b/cmake/waLBerlaHelperFunctions.cmake
index 8601ca863dcfc048decfe200534bca80ae409173..df759b16241646ceb8b056866d31aa175982d0d4 100644
--- a/cmake/waLBerlaHelperFunctions.cmake
+++ b/cmake/waLBerlaHelperFunctions.cmake
@@ -8,11 +8,55 @@
 # param ARGV0: optional boolean value if the flag should be added
 #
 #######################################################################################################################
-FUNCTION ( add_flag  _VAR  _FLAG )
+function ( add_flag  _VAR  _FLAG )
    if ( ARGC EQUAL 0 OR ARGV0 )
       set ( ${_VAR} "${${_VAR}} ${_FLAG}" PARENT_SCOPE )
    endif ( )
-ENDFUNCTION ( add_flag )
+endfunction ( add_flag )
+#######################################################################################################################
+
+
+
+#######################################################################################################################
+#
+# Function to handle source files of type .gen.py and .gen.cuda.py
+#
+# files .gen.py generate a .h and a .cpp file
+# files .gen.cuda.py generate a .h and a .cu file
+# Takes a list of source files that contain .py files, and returns a list of source files
+# where the generated version are added and the .py files are removed.
+# Additionally creates a custom build rule for the code generation
+#
+#######################################################################################################################
+function( handle_python_codegen sourceFilesOut codeGenRequiredOut )
+    set(result )
+    set(codeGenRequired NO)
+    foreach( sourceFile ${ARGN} )
+        if( ${sourceFile} MATCHES ".*\\.gen\\.py$" )
+            get_filename_component(sourceFile ${sourceFile} NAME)
+            if( ${sourceFile} MATCHES ".*\\.cuda\\.gen\\.py$" )
+                string(REPLACE ".cuda.gen.py" ".h"  genHeaderFile ${sourceFile})
+                string(REPLACE ".cuda.gen.py" ".cu" genSourceFile ${sourceFile})
+            else()
+                string(REPLACE ".gen.py" ".h"  genHeaderFile ${sourceFile})
+                string(REPLACE ".gen.py" ".cpp" genSourceFile ${sourceFile})
+            endif()
+            list(APPEND result ${CMAKE_CURRENT_BINARY_DIR}/${genSourceFile}
+                               ${CMAKE_CURRENT_BINARY_DIR}/${genHeaderFile})
+            add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${genSourceFile}
+                                      ${CMAKE_CURRENT_BINARY_DIR}/${genHeaderFile}
+                               DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${sourceFile}
+                               COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/${sourceFile}
+                               WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+            include_directories(${CMAKE_CURRENT_BINARY_DIR})
+            set(codeGenRequired YES)
+        else()
+            list(APPEND result ${sourceFile})
+        endif()
+    endforeach()
+    set( ${sourceFilesOut} ${result} PARENT_SCOPE )
+    set( ${codeGenRequiredOut} ${codeGenRequired} PARENT_SCOPE )
+endfunction ( handle_python_codegen )
 #######################################################################################################################