diff --git a/lib/crystal/codegen.rb b/lib/crystal/codegen.rb
index 2e57d8c29e6d3976d3b6d3a48c6f83b3547c3c49..7c865888930cb2eb77ba529d3c54e05afbbaa4a7 100644
--- a/lib/crystal/codegen.rb
+++ b/lib/crystal/codegen.rb
@@ -753,7 +753,9 @@ module Crystal
     def visit_struct_set(node)
       ptr = gep llvm_self, 0, @type.index_of_var(node.name)
       @last = @vars['value'][:ptr]
-      @builder.store @last, ptr
+      value = @last
+      value = @builder.load @last if node.type.c_struct? || node.type.c_union?
+      @builder.store value, ptr
     end
 
     def visit_union_alloc(node)
diff --git a/spec/codegen/c_struct_spec.rb b/spec/codegen/c_struct_spec.rb
index 3a28c4f11b8269c26c9754475fef6030843e0f48..bfcc51d50a4526d2260b21e95784618f70cf0981 100644
--- a/spec/codegen/c_struct_spec.rb
+++ b/spec/codegen/c_struct_spec.rb
@@ -57,4 +57,26 @@ describe 'Code gen: struct' do
       foo.bar.y
       )).to_i.should eq(2)
   end
+
+  it "codegens struct set inside struct" do
+    run(%q(
+      lib C
+        struct Bar
+          y : Int32
+        end
+
+        struct Foo
+          x : Int32
+          bar : Bar
+        end
+      end
+
+      foo = C::Foo.new
+      bar = C::Bar.new
+      bar.y = 2
+      foo.bar = bar
+
+      foo.bar.y
+      )).to_i.should eq(2)
+  end
 end