diff --git a/src/main/scala/leon/Main.scala b/src/main/scala/leon/Main.scala
index 9cc0dc9c6af811444024a05dd95b93c518df31eb..f238d4a854bd881c74a3205ef5b727a220e34ae1 100644
--- a/src/main/scala/leon/Main.scala
+++ b/src/main/scala/leon/Main.scala
@@ -27,7 +27,9 @@ object Main {
       solvers.isabelle.AdaptationPhase,
       solvers.isabelle.IsabellePhase,
       transformations.InstrumentationPhase,
-      invariant.engine.InferInvariantsPhase)
+      invariant.engine.InferInvariantsPhase,
+      genc.GenerateCPhase,
+      genc.CFileOutputPhase)
   }
 
   // Add whatever you need here.
@@ -53,9 +55,10 @@ object Main {
     val optHelp        = LeonFlagOptionDef("help",        "Show help message",                                         false)
     val optInstrument  = LeonFlagOptionDef("instrument",  "Instrument the code for inferring time/depth/stack bounds", false)
     val optInferInv    = LeonFlagOptionDef("inferInv",    "Infer invariants from (instrumented) the code",             false)
+    val optGenc        = LeonFlagOptionDef("genc",        "Generate C code",                                           false)
 
     override val definedOptions: Set[LeonOptionDef[Any]] =
-      Set(optTermination, optRepair, optSynthesis, optIsabelle, optNoop, optHelp, optEval, optVerify, optInstrument, optInferInv)
+      Set(optTermination, optRepair, optSynthesis, optIsabelle, optNoop, optHelp, optEval, optVerify, optInstrument, optInferInv, optGenc)
   }
 
   lazy val allOptions: Set[LeonOptionDef[Any]] = allComponents.flatMap(_.definedOptions)
@@ -151,6 +154,8 @@ object Main {
     import repair.RepairPhase
     import evaluators.EvaluationPhase
     import solvers.isabelle.IsabellePhase
+    import genc.GenerateCPhase
+    import genc.CFileOutputPhase
     import MainComponent._
     import invariant.engine.InferInvariantsPhase
     import transformations.InstrumentationPhase
@@ -163,11 +168,17 @@ object Main {
     val isabelleF    = ctx.findOptionOrDefault(optIsabelle)
     val terminationF = ctx.findOptionOrDefault(optTermination)
     val verifyF      = ctx.findOptionOrDefault(optVerify)
+    val gencF        = ctx.findOptionOrDefault(optGenc)
     val evalF        = ctx.findOption(optEval).isDefined
     val inferInvF    = ctx.findOptionOrDefault(optInferInv)
     val instrumentF  = ctx.findOptionOrDefault(optInstrument)
     val analysisF    = verifyF && terminationF
 
+    // Check consistency in options
+    if (gencF && !xlangF) {
+      ctx.reporter.fatalError("Generating C code with --genc requires --xlang")
+    }
+
     if (helpF) {
       displayVersion(ctx.reporter)
       displayHelp(ctx.reporter, error = false)
@@ -175,7 +186,7 @@ object Main {
       val pipeBegin: Pipeline[List[String], Program] =
         ClassgenPhase andThen
         ExtractionPhase andThen
-        new PreprocessingPhase(xlangF)
+        new PreprocessingPhase(xlangF, gencF)
 
       val verification = if (xlangF) VerificationPhase andThen FixReportLabels else VerificationPhase
 
@@ -189,6 +200,7 @@ object Main {
         else if (evalF) EvaluationPhase
         else if (inferInvF) InferInvariantsPhase
         else if (instrumentF) InstrumentationPhase andThen FileOutputPhase
+        else if (gencF) GenerateCPhase andThen CFileOutputPhase
         else verification
       }
 
diff --git a/src/main/scala/leon/genc/CFileOutputPhase.scala b/src/main/scala/leon/genc/CFileOutputPhase.scala
new file mode 100644
index 0000000000000000000000000000000000000000..f2b7797183da17ccb6e326a85a779a4ef58be9e2
--- /dev/null
+++ b/src/main/scala/leon/genc/CFileOutputPhase.scala
@@ -0,0 +1,54 @@
+/* Copyright 2009-2015 EPFL, Lausanne */
+
+package leon
+package genc
+
+import java.io.File
+import java.io.FileWriter
+import java.io.BufferedWriter
+
+object CFileOutputPhase extends UnitPhase[CAST.Prog] {
+
+  val name = "C File Output"
+  val description = "Output converted C program to the specified file (default leon.c)"
+
+  val optOutputFile = new LeonOptionDef[String] {
+    val name = "o"
+    val description = "Output file"
+    val default = "leon.c"
+    val usageRhs = "file"
+    val parser = OptionParsers.stringParser
+  }
+
+  override val definedOptions: Set[LeonOptionDef[Any]] = Set(optOutputFile)
+
+  def apply(ctx: LeonContext, program: CAST.Prog) {
+    // Get the output file name from command line options, or use default
+    val outputFile = new File(ctx.findOptionOrDefault(optOutputFile))
+    val parent = outputFile.getParentFile()
+    try {
+      if (parent != null) {
+        parent.mkdirs()
+      }
+    } catch {
+      case _ : java.io.IOException => ctx.reporter.fatalError("Could not create directory " + parent)
+    }
+
+    // Output C code to the file
+    try {
+      val fstream = new FileWriter(outputFile)
+      val out = new BufferedWriter(fstream)
+
+      val p = new CPrinter
+      p.print(program)
+
+      out.write(p.toString)
+      out.close()
+
+      ctx.reporter.info(s"Output written to $outputFile")
+    } catch {
+      case _ : java.io.IOException => ctx.reporter.fatalError("Could not write on " + outputFile)
+    }
+  }
+
+}
diff --git a/src/main/scala/leon/genc/GenerateCPhase.scala b/src/main/scala/leon/genc/GenerateCPhase.scala
new file mode 100644
index 0000000000000000000000000000000000000000..c30d32274db7370a8f9af5616df3cbe505b0389e
--- /dev/null
+++ b/src/main/scala/leon/genc/GenerateCPhase.scala
@@ -0,0 +1,20 @@
+/* Copyright 2009-2015 EPFL, Lausanne */
+
+package leon
+package genc
+
+import purescala.Definitions.Program
+
+object GenerateCPhase extends SimpleLeonPhase[Program, CAST.Prog] {
+
+  val name = "Generate C"
+  val description = "Generate equivalent C code from Leon's AST"
+
+  def apply(ctx: LeonContext, program: Program) = {
+    ctx.reporter.debug("Running code conversion phase: " + name)(utils.DebugSectionLeon)
+    val cprogram = new CConverter(ctx, program).convert
+    cprogram
+  }
+
+}
+
diff --git a/src/main/scala/leon/utils/DebugSections.scala b/src/main/scala/leon/utils/DebugSections.scala
index a0b790243a6dc309953d07ba02d504e463185880..b3133d700fed92bb500423201dc4288832b07319 100644
--- a/src/main/scala/leon/utils/DebugSections.scala
+++ b/src/main/scala/leon/utils/DebugSections.scala
@@ -24,6 +24,7 @@ case object DebugSectionXLang        extends DebugSection("xlang",        1 << 1
 case object DebugSectionTypes        extends DebugSection("types",        1 << 13)
 case object DebugSectionIsabelle     extends DebugSection("isabelle",     1 << 14)
 case object DebugSectionReport       extends DebugSection("report",       1 << 15)
+case object DebugSectionGenC         extends DebugSection("genc",         1 << 16)
 
 object DebugSections {
   val all = Set[DebugSection](
@@ -42,6 +43,7 @@ object DebugSections {
     DebugSectionXLang,
     DebugSectionTypes,
     DebugSectionIsabelle,
-    DebugSectionReport
+    DebugSectionReport,
+    DebugSectionGenC
   )
 }
diff --git a/src/main/scala/leon/utils/PreprocessingPhase.scala b/src/main/scala/leon/utils/PreprocessingPhase.scala
index 4a395912a6b9dc92a9828fc90bed421baf009c97..06f35dc3a47df0a48836e6137eaae96218745d39 100644
--- a/src/main/scala/leon/utils/PreprocessingPhase.scala
+++ b/src/main/scala/leon/utils/PreprocessingPhase.scala
@@ -9,7 +9,7 @@ import leon.solvers.isabelle.AdaptationPhase
 import leon.verification.InjectAsserts
 import leon.xlang.{NoXLangFeaturesChecking, XLangDesugaringPhase}
 
-class PreprocessingPhase(desugarXLang: Boolean = false) extends LeonPhase[Program, Program] {
+class PreprocessingPhase(desugarXLang: Boolean = false, genc: Boolean = false) extends LeonPhase[Program, Program] {
 
   val name = "preprocessing"
   val description = "Various preprocessings on Leon programs"
@@ -39,19 +39,27 @@ class PreprocessingPhase(desugarXLang: Boolean = false) extends LeonPhase[Progra
       CheckADTFieldsTypes                    andThen
       InliningPhase
 
-    val pipeX = if(desugarXLang) {
+    val pipeX = if (!genc && desugarXLang) {
+      // Do not desugar when generating C code
       XLangDesugaringPhase andThen
       debugTrees("Program after xlang desugaring")
     } else {
       NoopPhase[Program]()
     }
 
+    def pipeEnd = if (genc) {
+      // No InjectAsserts, FunctionClosure and AdaptationPhase phases
+      NoopPhase[Program]()
+    } else {
+      InjectAsserts  andThen
+      FunctionClosure andThen
+      AdaptationPhase
+    }
+
     val phases =
       pipeBegin andThen
       pipeX andThen
-      InjectAsserts andThen
-      FunctionClosure andThen
-      AdaptationPhase andThen
+      pipeEnd andThen
       debugTrees("Program after pre-processing")
 
     phases.run(ctx, p)