In Verilog , if the always@ block is executed sequentially , how do non-blocking statements work since they are executed parallely?
You have to separate the software execution semantics in simulation from the hardware semantics in synthesis. Verilog/SystmeVerilog gets used for both. And sometimes the terminology gets reused in different ways, especially the word sequential.

Each always block represents a concurrent process or behavior based on the procedural code you write associated with the block. Certainly styles of code (but not all) can be synthesized into hardware, and that hardware is typically divided into two categories of logic: sequential and combinatorial.

Sequential logic stores state information over time where as combinatorial logic is totally dependent on the immediate inputs to the block. In software, sequential code simply means the is a defined order of execution between statements.

always @(*) begin
      a = b + c;
      d = a + e;
   end


The code above represents combinatorial logic, but the code between the begin/end executes sequentially. If you change the code to

always @(posedge clk) begin
      a = b + c;
      d = a + e;
end


now you still have sequentially executing statements, but the code now represents a mixture of sequential and combinational logic (only d is sequential). But if you replace the blocking to non-blocking assignments

  always @(posedge clk) begin
          a &lt;= b + c;
          d &lt;= a + e;
  end


You still have two assignment statements executing in sequence, but since the update to a is deferred, you now have two sequential logic elements in parallel. Its the same has if you had written the last example in separate always blocks. 

  always @(posedge clk) begin
          a &lt;= b + c;
  end
  always @(posedge clk) begin
          d &lt;= a + e;
  end