diff --git a/preprocessor/DataTree.cc b/preprocessor/DataTree.cc
index ba94916556c505edab8956f60f3320d9c4c56e50..e748e7598b94e3fd66483e7d4568e5e154cda5a9 100644
--- a/preprocessor/DataTree.cc
+++ b/preprocessor/DataTree.cc
@@ -707,3 +707,48 @@ DataTree::writePowerDeriv(ostream &output) const
            << "    }" << endl
            << "}" << endl;
 }
+
+void
+DataTree::writeNormcdfCHeader(ostream &output) const
+{
+#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__)
+  if (isTrinaryOpUsed(oNormcdf))
+    output << "#ifdef _MSC_VER" << endl
+           << "double normcdf(double);" << endl
+           << "#endif" << endl;
+#endif
+}
+
+void
+DataTree::writeNormcdf(ostream &output) const
+{
+#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__)
+  if (isTrinaryOpUsed(oNormcdf))
+    output << endl
+           << "#ifdef _MSC_VER" << endl
+           << "/*" << endl
+           << " * Define normcdf for MSVC compiler" << endl
+           << " */" << endl
+           << "double normcdf(double x)" << endl
+           << "{" << endl
+           << "#if _MSC_VER >= 1700" << endl
+           << "  return 0.5 * erfc(-x * M_SQRT1_2);" << endl
+           << "#else" << endl
+           << "  // From http://www.johndcook.com/blog/cpp_phi" << endl
+           << "  double a1 =  0.254829592;" << endl
+           << "  double a2 = -0.284496736;" << endl
+           << "  double a3 =  1.421413741;" << endl
+           << "  double a4 = -1.453152027;" << endl
+           << "  double a5 =  1.061405429;" << endl
+           << "  double p  =  0.3275911;" << endl
+           << "  int sign = (x < 0) ? -1 : 1;" << endl
+           << "  x = fabs(x)/sqrt(2.0);" << endl
+           << "  // From the Handbook of Mathematical Functions by Abramowitz and Stegun, formula 7.1.26" << endl
+           << "  double t = 1.0/(1.0 + p*x);" << endl
+           << "  double y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x);" << endl
+           << "  return 0.5*(1.0 + sign*y);" << endl
+           << "#endif" << endl
+           << "}" << endl
+           << "#endif" << endl;
+#endif
+}
diff --git a/preprocessor/DataTree.hh b/preprocessor/DataTree.hh
index ce908408acaddb22680bfcde055450d287630c5a..83e59471cb76ce29bd016a0d46c3bf3076c668ed 100644
--- a/preprocessor/DataTree.hh
+++ b/preprocessor/DataTree.hh
@@ -239,6 +239,10 @@ public:
   void writePowerDerivCHeader(ostream &output) const;
   //! Write getPowerDeriv in C
   void writePowerDeriv(ostream &output) const;
+  //! Write the C Header for normcdf when use_dll is used
+  void writeNormcdfCHeader(ostream &output) const;
+  //! Write normcdf in C
+  void writeNormcdf(ostream &output) const;
   //! Thrown when trying to access an unknown variable by deriv_id
   class UnknownDerivIDException
   {
diff --git a/preprocessor/DynamicModel.cc b/preprocessor/DynamicModel.cc
index f9720fa1c569564d96ffcd5330beafeca8da7258..cc16f5aaed7693c85c15681d2f7827ad58cec34e 100644
--- a/preprocessor/DynamicModel.cc
+++ b/preprocessor/DynamicModel.cc
@@ -1620,11 +1620,13 @@ DynamicModel::writeDynamicCFile(const string &dynamic_basename, const int order)
 
   // Write function definition if oPowerDeriv is used
   writePowerDerivCHeader(mDynamicModelFile);
+  writeNormcdfCHeader(mDynamicModelFile);
 
   // Writing the function body
   writeDynamicModel(mDynamicModelFile, true, false);
 
   writePowerDeriv(mDynamicModelFile);
+  writeNormcdf(mDynamicModelFile);
   mDynamicModelFile.close();
 
   mDynamicMexFile.open(filename_mex.c_str(), ios::out | ios::binary);
@@ -4883,6 +4885,7 @@ DynamicModel::writeResidualsC(const string &basename, bool cuda) const
   // Write function definition if oPowerDeriv is used
   // even for residuals if doing Ramsey
   writePowerDerivCHeader(mDynamicModelFile);
+  writeNormcdfCHeader(mDynamicModelFile);
 
   mDynamicModelFile << "void Residuals(const double *y, double *x, int nb_row_x, double *params, double *steady_state, int it_, double *residual)" << endl
                     << "{" << endl;
@@ -4900,6 +4903,7 @@ DynamicModel::writeResidualsC(const string &basename, bool cuda) const
 		    << "}" << endl;
 
   writePowerDeriv(mDynamicModelFile);
+  writeNormcdf(mDynamicModelFile);
   mDynamicModelFile.close();
 
 }
@@ -4931,6 +4935,7 @@ DynamicModel::writeFirstDerivativesC(const string &basename, bool cuda) const
 
   // Write function definition if oPowerDeriv is used
   writePowerDerivCHeader(mDynamicModelFile);
+  writeNormcdfCHeader(mDynamicModelFile);
 
   mDynamicModelFile << "void FirstDerivatives(const double *y, double *x, int nb_row_x, double *params, double *steady_state, int it_, double *residual, double *g1, double *v2, double *v3)" << endl
                     << "{" << endl;
@@ -4988,6 +4993,7 @@ DynamicModel::writeFirstDerivativesC_csr(const string &basename, bool cuda) cons
 
   // Write function definition if oPowerDeriv is used
   writePowerDerivCHeader(mDynamicModelFile);
+  writeNormcdfCHeader(mDynamicModelFile);
 
   mDynamicModelFile << "void FirstDerivatives(const double *y, double *x, int nb_row_x, double *params, double *steady_state, int it_, double *residual, int *row_ptr, int *col_ptr, double *value)" << endl
                     << "{" << endl;
@@ -5089,6 +5095,7 @@ DynamicModel::writeSecondDerivativesC_csr(const string &basename, bool cuda) con
 
   // write function definition if oPowerDeriv is used
   writePowerDerivCHeader(mDynamicModelFile);
+  writeNormcdfCHeader(mDynamicModelFile);
 
   mDynamicModelFile << "void SecondDerivatives(const double *y, double *x, int nb_row_x, double *params, double *steady_state, int it_, double *residual, int *row_ptr, int *col_ptr, double *value)" << endl
                     << "{" << endl;
@@ -5151,8 +5158,8 @@ DynamicModel::writeSecondDerivativesC_csr(const string &basename, bool cuda) con
   mDynamicModelFile << "}" << endl;
 
   writePowerDeriv(mDynamicModelFile);
+  writeNormcdf(mDynamicModelFile);
   mDynamicModelFile.close();
-
 }
 
 void
@@ -5182,6 +5189,7 @@ DynamicModel::writeThirdDerivativesC_csr(const string &basename, bool cuda) cons
 
   // Write function definition if oPowerDeriv is used
   writePowerDerivCHeader(mDynamicModelFile);
+  writeNormcdfCHeader(mDynamicModelFile);
 
   mDynamicModelFile << "void ThirdDerivatives(const double *y, double *x, int nb_row_x, double *params, double *steady_state, int it_, double *residual, double *g1, double *v2, double *v3)" << endl
                     << "{" << endl;
@@ -5277,6 +5285,7 @@ DynamicModel::writeThirdDerivativesC_csr(const string &basename, bool cuda) cons
   mDynamicModelFile << "}" << endl;
 
   writePowerDeriv(mDynamicModelFile);
+  writeNormcdf(mDynamicModelFile);
   mDynamicModelFile.close();
 
 }
diff --git a/preprocessor/ModFile.cc b/preprocessor/ModFile.cc
index 3ee5612f9b35986b68bac0a2134ac960df70a0d6..173f9b669c36046e347b9116b608aafc189975af 100644
--- a/preprocessor/ModFile.cc
+++ b/preprocessor/ModFile.cc
@@ -739,12 +739,6 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
         }
     }
 #endif
-  if (use_dll && msvc)
-    if (dynamic_model.isTrinaryOpUsed(oNormcdf))
-      {
-        cerr << "ERROR: normcdf() function is not supported with USE_DLL option and older MSVC compilers; use Cygwin, MinGW or upgrade your MSVC compiler to 11.0 (2012) or later." << endl;
-        exit(EXIT_FAILURE);
-      }
 #endif
 
   // Compile the dynamic MEX file for use_dll option
diff --git a/preprocessor/StaticModel.cc b/preprocessor/StaticModel.cc
index 23e5e1f4d6b96d4a7310d65e114022c1d374f6e9..251cbe1e044dd284592bb866989cbe929a337e3a 100644
--- a/preprocessor/StaticModel.cc
+++ b/preprocessor/StaticModel.cc
@@ -1611,12 +1611,14 @@ StaticModel::writeStaticCFile(const string &func_name) const
 
   // Write function definition if oPowerDeriv is used
   writePowerDerivCHeader(output);
+  writeNormcdfCHeader(output);
 
   // Writing the function body
   writeStaticModel(output, true, false);
   output << "}" << endl << endl;
 
   writePowerDeriv(output);
+  writeNormcdf(output);
   output.close();
 
   output.open(filename_mex.c_str(), ios::out | ios::binary);