diff --git a/preprocessor/DynareMain.cc b/preprocessor/DynareMain.cc
index 5aec0a9b4dfe3af81268e0c00638543ef2735361..e40afaadc40677a8e2b022484cfb8bb44fc1e161 100644
--- a/preprocessor/DynareMain.cc
+++ b/preprocessor/DynareMain.cc
@@ -46,7 +46,8 @@ void
 usage()
 {
   cerr << "Dynare usage: dynare mod_file [debug] [noclearall] [savemacro[=macro_file]] [onlymacro] [nolinemacro] [notmpterms] [warn_uninit]"
-       << " [console] [parallel[=cluster_name]] [conffile=parallel_config_path_and_filename] [parallel_slave_open_mode] [parallel_test]"
+       << " [console] [parallel[=cluster_name]] [conffile=parallel_config_path_and_filename] [parallel_slave_open_mode] [parallel_test] "
+       << " [-D<variable>[=<value>]]"
 #if defined(_WIN32) || defined(__CYGWIN32__)
        << " [cygwin] [msvc]"
 #endif
@@ -81,6 +82,7 @@ main(int argc, char **argv)
   string cluster_name;
   bool parallel_slave_open_mode = false;
   bool parallel_test = false;
+  map<string, string> defines;
 
   // Parse options
   for (int arg = 2; arg < argc; arg++)
@@ -144,6 +146,27 @@ main(int argc, char **argv)
               cluster_name = string(argv[arg] + 9);
             }
         }
+      else if (strlen(argv[arg]) >= 2 && !strncmp(argv[arg], "-D", 2))
+        {
+          if (strlen(argv[arg]) == 2)
+            {
+              cerr << "Incorrect syntax for command line define: the defined variable "
+                   << "must not be separated from -D by whitespace." << endl;
+              usage();
+            }
+
+          size_t equal_index = string(argv[arg]).find('=');
+          if (equal_index != string::npos)
+            {
+              string key = string(argv[arg]).erase(equal_index).erase(0,2);
+              defines[key] = string(argv[arg]).erase(0, equal_index+1);
+            }
+          else
+            {
+              string key = string(argv[arg]).erase(0,2);
+              defines[key] = "1";
+            }
+        }
       else
         {
           cerr << "Unknown option: " << argv[arg] << endl;
@@ -164,7 +187,7 @@ main(int argc, char **argv)
   MacroDriver m;
 
   stringstream macro_output;
-  m.parse(argv[1], macro_output, debug, no_line_macro);
+  m.parse(argv[1], macro_output, debug, no_line_macro, defines);
   if (save_macro)
     {
       if (save_macro_file.empty())
diff --git a/preprocessor/macro/MacroDriver.cc b/preprocessor/macro/MacroDriver.cc
index dc1a14964a14a3df1ef8ebdbc8f9d3992a521dab..f2f2477eae4573db3ee4a84cf3fed795df02380b 100644
--- a/preprocessor/macro/MacroDriver.cc
+++ b/preprocessor/macro/MacroDriver.cc
@@ -36,7 +36,7 @@ MacroDriver::~MacroDriver()
 }
 
 void
-MacroDriver::parse(const string &f, ostream &out, bool debug, bool no_line_macro)
+MacroDriver::parse(const string &f, ostream &out, bool debug, bool no_line_macro, map<string, string> defines)
 {
   file = f;
 
@@ -53,6 +53,9 @@ MacroDriver::parse(const string &f, ostream &out, bool debug, bool no_line_macro
     an @#endif or an @#endfor - but no newline - no longer trigger an error.
   */
   stringstream file_with_endl;
+  for (map<string,string>::iterator it=defines.begin();
+       it!=defines.end(); it++)
+    file_with_endl << "@#define " << it->first << " = " << it->second << endl;
   file_with_endl << in.rdbuf() << endl;
 
   lexer = new MacroFlex(&file_with_endl, &out, no_line_macro);
diff --git a/preprocessor/macro/MacroDriver.hh b/preprocessor/macro/MacroDriver.hh
index 345c8e51b7fadeb1d1b31ef146b23457df6af0b5..92c95dfc618ea65bef60a534847f6331ae06d6f2 100644
--- a/preprocessor/macro/MacroDriver.hh
+++ b/preprocessor/macro/MacroDriver.hh
@@ -176,7 +176,7 @@ public:
 
   //! Starts parsing a file, returns output in out
   /*! \param no_line_macro should we omit the @#line statements ? */
-  void parse(const string &f, ostream &out, bool debug, bool no_line_macro);
+  void parse(const string &f, ostream &out, bool debug, bool no_line_macro, map<string,string> defines);
 
   //! Name of main file being parsed
   string file;